文件系统
Unix文件系统如何存储文件内容、文件属性和目录?
Unix将磁盘块分成三部分(文件系统被分为三个区域):
数据区:存放文件内容;
i-节点表:存放文件属性;记录文件的大小、所有者和最近修改时间等。(标识为2的i-节点位于文件系统i-节点表的第三个位置)为何是第三个位置,难道第一个位置超级块?但超级块并未在i-节点表中。
超级块:存放文件系统本身。如记录每个区域大小,存放未被使用的磁盘块信息。
若创建一个新文件,其具体如何实现?文件有内容和属性,内核将文件内容存放在数据区,文件属性存放在i-节点,文件名存放在目录。
1.存储属性:内核先找到一个空的i-节点,图中内核找到i-节点47,内核将文件的信息记录在其中。
2.存储数据:由于该文件需要3个存储磁盘块,因此内核从自由块的列表中找出三个自由块。自由块列表在存放在超级快中。自由表选出了627、200、992三个自由块。内核将缓冲区的第一块数据复制到块627,下一块数据复制到块200,最后一块复制到块992。为何块号不是递增的,是不是自由块查找时不是线性查找?
3.记录分配情况:文件内容按顺序存放在块627、200、922中,内核在i-节点的磁盘分布区记录了上述块序列。磁盘分布区是一个磁盘块序号的列表,这3个编号放在最开始的3个位置。
4.添加文件名到目录:新文件名为userlist。内核将入口(47,userlist)添加到目录文件。文件名和i-节点号之间的对应关系将文件名和文件的内容及属性连接了起来。
我们通过命了ls -i就会看到各个文件的i-节点号。我们执行ls -ia:
有些文件都指向同一个i-节点,说明这两个文件时同一个文件的两个不同的名字。另外,“.”和“..”的i-节点号都是2,所以其都指向同一个目录。大多数情况下,它们不相同,但根目录比较特别,当Unix命了mkfs创建了一个文件系统,mkfs将根目录父目录指向自己。
当我们读一个文件时:(cat userlist)
1.在目录中寻找文件名:内核在目录文件中寻找包含字符串userlist的记录,userlist所在的记录包含编号为47的i-节点号。
2.定为i-节点47并读取其内容:内核在文件系统中的i-节点区域找到i-节点47.
3.访问存储内容文件的数据块:cat不断调用read函数,使内核不断将字节从磁盘复制到内核缓冲区,进而达到用户空间。
Unix文件系统如何跟踪大文件?
若一个文件需要14个数据块存储它的内容,因此,分配链表包含14个块的编号。但文件的i-节点只包含一个含有13个项的分配链表。Unix将分配链表中前10个编号放在i-节点中,将最后4个编号放到一个数据块中。
即分配链表中前10个块编号指向的是文件的实际数据,若分配链表有多于10个项,则剩下的块编号不存储在i-节点,而是存储在数据区。存放多余编号的数据块的编号存储在i-节点的第11项中。即假设一个文件需要14个数据块存储,前10个数据块存放的自由数据块号存放在i-节点中,后四个自有数据块号存放在某自由数据块中,这个存放这四个数据块号的数据块号存放在i-节点的第11项中。这个块被称为间接块。
若间接块饱和,Unix将引入第二个额外块,即将剩余数据存放在某自由数据块中,这个自由数据块存放在i-节点的第12项中。但实际上i-节点的第12项并不存放第二个额外块的编号,而是存放那个存储着第2、3、4及后续额外块的编号的块的编号。即i-节点第12项存放的是包括第2个间接块及以后的间接块的编号。
我们来假设具体数据进行解释:我们可以看到i-节点前10项存储自由数据块,而第11项存放间接块的编号,这里是188。数据块188号中存放了另外剩余的3个自有数据块。如果间接块饱和,Unix实际将i-节点的第12项存放二级间接块及之后其他额外块(E2,E3,E4...),而这些间接块又将指向其他数据块,而数据块中存储了需要存放数据的数据块。
若二级间接块包括了,内核将开辟另一个新的二级间接块,这个新的二级间接块并不放在i-节点中,而是创建一个三级间接块来存放二级间接块的编号及这个文件将来所需要的所有间接二级块的编号,i-节点的最后一项存放的是记录这个三级间接块的编号。
若文件达到了极限,可以创建一个由更大的磁盘块构成的文件系统。当创建该文件系统时,不仅能够定义i-节点表和数据区的大小,而且能够定义磁盘块的大小。
参考:《Unix/Linux 编程实践教程》