文章目录
- 文件系统
- 磁盘
- 磁盘逻辑抽象
- inode
- 软硬链接
- 软链接
- 硬链接
文件系统
文件分为打开的文件和没有被打开的文件,而只有打开的文件是在内存的,也就是我们之前讲的,然而大部分文件都不是被打开的(当前不需要被访问的),它们都在磁盘中存放,显而易见,他们也是需要被管理的。而对于这部分文件的核心就是我们需要快速的定位它们在磁盘中的位置。
文件的管理:
- 打开文件进行管理
- 没有被打开的文件也要在磁盘中进行管理
对于打开文件和没有被打开文件的管理,我们称之为文件系统。
磁盘
磁盘是硬件,物理存储结构。
磁盘一片有两面,每一面都有一个磁头,可以左右移动,盘面是可以旋转的,所以这两个一结合,磁头就可以访问磁盘中的任意位置。一个盘面有很多的磁道,每一圈磁道可以有很多的扇形的扇区。而扇区是磁盘的最小存储单元(512字节)。
如果我们想向一个扇区写入,应该如何寻址?
- 选择磁头(head)
- 选择该面的那一个磁道(cylinder)
- 选择哪一扇区(sector)
这样的寻址方式为CHS定位法。
现在可以向一个扇区进行写入,就可以向任意一个/多个扇区进行写入,可以多个扇区进行写入,当然也可以进行随机的读写。
磁盘逻辑抽象
一圈一圈的磁道我们可以想象一下一个圆可以抽象成一个长方形,所以我们的一圈圈磁道就是一个一个的圆形,所以我们可以把一个盘面抽象成一个数组,而数组元素的大小就是扇区,所以我们可以把整个磁盘也就是多个盘面抽象成一个超级大的数组。
所以我们根据数组的下标,然后根据每个盘面多大,每圈的磁道多大,就可以通过计算,定位到一个扇区的CHS地址。
操作系统可以根据扇区为单位进行存取,也可以基于文件系统以文件块为单位进行存取。Linux中OS一般读取的大小为8个扇区的大小(4KB),所以每次只需要给一个初始地址,然后向后读取8个单位即可,这样的以8个扇区为单位大小的起始地址为LBA地址。
最终结论: 对于存储设备的管理就转化为了对数组的增删查改。
假设我们现在有500GB的空间需要我们管理,如果我们把这500GB的空间整体使用,从技术层面来说当然是可以的,但是我们用起来非常的不方便,所以我们会把一个非常大的空间进行分区,然后对分区进行管理,只需要把一个分区管好其他的分区可以复用这个分区的策略来进行管理。
然后可以让一个分区进行分组,然后只需要把一个组管好,其他组可以复用这个组的方式,所以对500GB的管理就转化为了对一个组的管理。所以磁盘也是设备
操作系统中管理文件无非即使我自己的文件信息和很多管理我的文件的信息,所以在文件系统开始用之前一定要把管理数据写入到块组中,而我的文件信息无非就是内容+属性,Linux下属性和内容是分开存储的。
格式化就是把磁盘中管理我们自己文件的信息初始化,相当于恢复出厂设置。
inode
Linux下,使用ls 加个-li选项就可以看到我们文件的indode。
图中圈红的就是我们自己文件的inode。一般情况下一个文件一个inode,基本上inode每个文件都要有,inode在整个分区具有唯一性,Linux内核中识别文件和文件名无关,之和inode有关。由于文件我们用户用的是文件名,但是内核用的是inode,所以一定存在文件名和inode的映射关系。
我们在看这个图,我们会发现每个块组中包含很多的属性,我们看一下每个属性代表什么含义。
- 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
- GDT,Group Descriptor Table:块组描述符,描述块组属性信息。
- 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没
有被占用 - inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
- inode表:存放文件属性 如 文件大小,所有者,最近修改时间等
- 数据区:存放文件内容
inode中除了存放的有文件的属性之外,还有一个block的数组,表示自己的内容放在哪几个块中。一般来说这个数组的大小是15。后两个位置并不值就存放内容,倒数第二个存放二级映射,而倒数第一个存放三级映射。
所以后四个是存放我们自己的文件内容,而前两个是存放管理文件的内容。一般超级块没隔几个块组就会有一个,因为为了防止因为超级块坏的话整个磁盘就会挂掉,所以为了防止这种情况,如果一个坏了,就可以去后面把正确的拷贝回来,可以增强容错率。
对于普通文件来说,创建一个普通文件只需要通过inode位图找到一个没有用过的inode,然后把位图修改成1,通过inode表,索引找到inode,把属性填进去,把内容放进block中,修改blocd的位图,把内容存在的block的下标填入自己的block数组中,就搞定了。
对于目录文件来说,它的创建方式和普通文件完全一样,只不过它的内容是它目录下的文件的文件名和inode的映射关系。而删除一个文件只需要修改一个文件对应的inode位图和block位图即可。
上面说的所有都是在一个分区中,那么我们如何区分在哪一个分区呢?
每一个文件都有路径,可以通过判断路径的前缀来判断文件在哪一个分区下。
如何查找一个文件?
一般查找一个文件是,不是是打开还是怎样,文件的路径都是我们用户提供,所以每个进程都会有一个CWD,所以OS只需要通过用户给的路径确定在哪一个分区,然后依次根据文件名和inode的映射关系就可以找到我们需要的文件。
软硬链接
软链接
Linux中可以通过ln -s 的方式来建立软链接。
可以发现软链接是一个独立的文件,有独立的inode,文件的内容就是指向文件的路径。类似于Windows中的快捷方式。软链接就是普通文件。
硬链接
Linux中可以通过ln 的方式来建立软链接。
圈红的为硬链接数。
可以发现硬链接的inode和指向的文件是相同的,所以硬链接不是一个独立的文件,他是一个目录内部文件名和inode的映射关系,所以一个文字只有在硬链接数为0时,才会被真正的删除。
一般目录文件不能被建立硬链接,因为我们在查找的时候,如果目录被创建了硬链接,在实现某种查找算法是无法区分硬链接指向的目录和真正的目录、,很可能会出现死循环。所以一般是不允许创建目录的硬链接。
但是Linux中存在目录的硬链接,这个被OS的特殊处理,我们用户是不允许创建硬链接的。