linux文件系统中一些重要概念的分析



文件控制块(FCB,File Control Block)

linux文件系统使用目录来组织文件。目录也被组织成文件存放在磁盘上,成为目录文件。每个文件都在它属于的目录文件中登记一个 文件目录项,这个文件目录项就是 文件控制块。下图就是一个目录文件的物理结构示意图。遍历该结构,就可以找到该目录下的所有文件的 文件控制块
文件控制块1
文件控制块2
...
文件控制块n

文件控制块包含了文件除数据以外的控制信息,例如有关文件存取控制的信息(文件名、存取权限等)、有关文件逻辑结构和物理结构的信息、有关文件管理的信息(创建时间等)。因此,一个文件控制块的存储空间还是很大的。如果将文件控制块都直接保存在目录文件中,那么目录文件将会占据较多的物理块。遍历目录时就会读取多个物理快,从而降低了检索文件的速度。为了解决这个问题,linux引入了名为 索引节点的数据结构。

索引节点(inode)

为了减少目录文件所占的物理块,linux将 文件控制块一分为二,第一部分是文件名,第二部分是其他信息。其他信息被组织成定长的数据结构,称为 索引节点。每个 索引节点都有一个编号,称为 索引号。每个 文件目录项只保存文件名及文件名对应的 索引号。这样 文件目录项中只剩下14字节的文件名和2字节的 索引号,一个512字节的物理块就可以保存32个 文件目录项。也就是说,一个包含32个文件或子目录的目录,只占据1个物理块。可见,目录文件占据的物理块被大大减少。下图是使用了索引节点的物理文件的物理结构示意图。
文件名1
索引号1
文件名2
索引号2
...
...
文件名n
索引号n

提高文件访问速度,关键在于减少访问磁盘的次数,即减少访问读取物理块的数量。

外存索引节点

索引节点被保存在外存中,称为外存索引节点。

内存索引节点、内存索引节点表

索引节点存放在外存中。对某个文件的访问,会经常使用到它的 索引节点,这样就会频繁地在内存和外存之间来回拷贝 索引节点,效率较低。为了避免这个问题,linux在系统主存中开辟了一张 内存索引节点表,该表共有100个表项,每个表项就是一个索引节点,称为 内存索引节点。需要使用文件信息时,先到 内存索引节点表中查找,如果找到则直接使用,否则将外存中的索引节点拷贝到 内存索引节点表中,并使用之。使用内存索引节点表,不但能够加快文件访问速度,而且便于实现文件共享,这点在后面会提到。下图是内存索引节点表的示意图
索引节点1
索引节点2
...
索引节点n

内存索引节点表又被称为 活动索引节点表内存索引节点又被称为 活动索引节点

系统打开文件表

用户使用文件系统提供的API,按名访问文件,而不是直接访问 索引节点。访问索引节点是文件系统的事情。文件系统必须根据文件名,在目录中查找到该文件的 索引号,找到 索引号后才能从 内存索引节点表中查找索引节点。虽然 索引节点可能被缓存在 内存索引节点表中,但是在目录中查找 索引号需要访问磁盘,效率是低下的。
为了解决这个问题,文件系统在内存中建立了一张 系统打开文件表,该表共有100个表项。每个表项中存放了一个已打开的文件的 索引号和其它信息。在文件被打开的时候,文件系统会在 系统打开文件表中登记相应的表项。如果以后需要访问该文件,文件系统会首先在 系统打开文件表中查找该文件的 索引号。下图是 系统打开文件表的示意图。
索引号1
其它信息1
索引号2
其它信息2
...
...
索引号n
其它信息n

系统打开文件表不但能提高文件访问效率,还便于实现文件共享,这点在后面会提到。

用户打开文件表

每个进程拥有一张 用户打开文件表,该表有15个表项。它的表项类似于指针,指向 系统打开文件表的表项。下图是用户打开文件表的示意图。
文件号1
指针1
文件号2
指针2
...
...
文件号n
指针n

这里没有使用文件名来标识一个文件,而是使用了文件号。 用户打开文件表便于实现文件共享,这点在后面提到。

索引表

那么,索引节点是怎么描述文件数据的物理存储的呢?我们知道,文件数据存放在一个或多个物理块中,索引节点必须维护这些物理块的块号,才能真正找到文件数据。linux使用 索引表来管理存放文件数据的物理块。 索引表的每个表项都是一个物理块号。遍历 索引表,就可以访问存放文件数据的所有物理块。那么,索引表是如何存放的呢? 索引表同文件数据一样,也存放在物理块中。 索引节点中包含了 索引表所在物理块的块号,因此通过 索引节点就可以访问到 索引表,从而访问到文件数据。
如果文件很大,文件数据占用的物理块可能很多,索引表也会很大,那么,如果一个物理块不足以存放索引表怎么办?linux采用了多重索引表。
多重索引表是这样的。
  1. 每个文件的索引表规定为13个索引项,每个项4个字节,登记一个物理块。
  2. 索引项0-9中登记的是存放文件数据的物理块号。
  3. 索引项10登记的是存放一张二级索引表的物理块号。二级索引表拥有128个索引项,每个索引项登记的是存放文件数据的物理块号。
  4. 索引项11登记的是存放一张三级索引表的物理块号。三级索引表拥有128个索引项,每个索引项登记的是存放一张二级索引表的物理块号。二级索引表的内容同上。
  5. 索引项11登记的是存放一张四级索引表的物理块号。四级索引表拥有128个索引项,每个索引项登记的是存放一张三级索引表的物理块号。三级索引表的内容同上。
根据多重索引表的结构,我们可以计算出linux支持的最大文件体积。(10+128+128*128+128*128*128)*512字节 约等于128*128*128*512,即2的30次方,大约1G字节。

文件系统在外存上的组织安排。

磁盘被分成几个分区,每个分区称为一个文件卷。文件系统管理一个文件卷。文件卷被分成若干柱面、磁道和扇区。每个扇区为512字节,又称为物理块。0号物理块用于系统引导,1号物理块为超级块(super block),用于记录文件系统管理所需的信息。2-k块,用于存放 外存索引节点表,k+1-n块,用于存在文件数据,n+1块的用途还不清楚。

文件的共享

linux上的文件共享分为两种:静态共享和动态共享。静态共享是指多个文件对应同一个物理存储。这可以通过文件连接和符号连接来实现。动态共享,是指不同进程并发地访问同一文件。动态共享是运行时的概念,进程结束了,共享关系也就消失了。

文件连接和普通文件一样被登记在目录文件中,他们的区别在于,文件连接会登记被链接文件的索引号,而符号连接只是登记被链接的文件的路径。

下面重点看看动态共享是如何实现的。

动态共享又分为两种情况:共享读写指针和不共享读写指针。如果两个进程合作访问一个文件,那就需要共享读写指针,这种情况常见于父子进程中。如果两个进程需要独立地、互不影响地访问一个文件,那就需要各自拥有独立的读写指针。

文件的读写指针是保存在系统打开文件表项中的。两个进程如果需要共享某个文件的读写指针,那么该文件在它们的用户打开文件表中的表项,应该都指向系统打开文件表的同一表项。 相反,则指向系统打开文件表的两个不同表项,只不过这两个表项都指向同一个索引节点

系统打开文件表的表项中除了含有读写指针f_offset,还有文件的访问计数f_count和内存索引节点的指针f_inode。f_count指出使用同一系统打开文件表项的进程数,注意不是使用同一文件的进程数。f_count是系统打开文件表项能够释放的标志。





  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值