`
jilinzm
  • 浏览: 22505 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

linux文件系统实现浅析(转)

阅读更多

之前有两篇文章整理过linux虚拟文件系统 的结构,和linux文件读写 的 流程。其中一些由具体文件系统类型来实现的地方并没有深入叙述,只是说这是由具体的文件系统来实现的。比如,读写文件的时候,文件的读写位置怎么对应到实 际的磁盘块呢?这是由具体的文件系统来实现的;再比如,寻找一个文件路径的时候,怎么知道XXX目录下是否有YYY文件存在呢?这也是由具体的文件系统来 实现的。
前些天同事问起linux下inode的含义,我也就此整理一下自己的思路,看看具体的文件系统大致需要实现什么样的功能,并且可以怎样去实现。

inode
先从inode说起。文件系统中的文件形成了一个树型结构,其中的每一个结点就是一个文件(目录也是文件),对应一个inode。inode的具体结构因 文件系统类型的不同而异,但是大体上应该包含如下信息:文件所有者(包括uid、gid)、权限位、文件大小、时间(创建时间、修改时间等)、文件内容。 其中最值得一说的是文件内容。
文件有目录和普通文件之分,这两者的内容有着不同的含义,其内容的组织也可能有着不同的结构。

对于普通文件来说,其内容就是用户能够看到的文件内容。当用户程序通过系统调用读写文件时,需要通过某种索引结构来知道文件中某个offset的数据应该 在哪个磁盘块上,然后转换成对该块的读写请求。当文件的内容很小时,文件内容的索引信息可以完全存放在inode结点中;如果文件很大,索引也会很 大,inode结点可能装不下,就需要分配新的块来存放这些索引信息。而文件的内容则多半是放在inode结点之外的,依靠inode里面的索引信息来找 到它们。
比如ext2文件系统中,文件内容的索引结构如下(摘自《ULK3》):

文件内容小于12个块的部分,其块号直接存放在inode中的i_block结构中;从第13块开始,使用一级间接索引,之后随偏移的增大又扩展到二级、三级间接索引。

对于目录,其内容一般是结构化的信息,描述了该目录下的文件的情况(主要包括每个文件的名字、inode号、等)。这是需要由具体的文件系统来解释的,用 户看到这些原始内容是没有意义的。只有由具体文件系统将其解释为文件列表后,对用户才有意义。当用户程序寻找一个文件路径时,通过当前目录的inode, 就能遍历到目录中的每一个结点(文件名+inode号)。匹配了下一级文件的名字以后,就能得到其对应的inode号,从而找到下一级文件的inode。 这些下一级文件的信息也是因为其信息大小的不同,而直接存放在inode结点中,或另外的块中。
比如ext2文件系统中,目录信息结构如下(摘自《ULK3》):

对于每一个下一级文件,记录了它的inode号、文件名、以及文件类型。

符号链接是一种特殊的文件。作为对另一个文件的代指,符号链接文件的内容就是它所代指的文件的路径。这个文件路径信息保存在inode或被inode引用 的块中。具体的文件系统类型会实现其特定的读符号链接的方法。用户也可以通过readlink系统调用读到符号链接指向的文件路径。
在打开一个符号链接时,它代指的文件路径(也就是符号链接文件的内容)一般并不被用户程序所关心。内核会对此做一层包装,让用户程序自动访问到它所代指的文件的路径上去。

说了符号链接,也顺便提一下硬链接。硬链接并不会生成新的inode,而是同一个inode被包含在多个目录结点中,从而存在多个文件路径可以找到该文件。

super_block
前面描述了通过一个目录结点找到下一级文件的问题,那么文件系统中的第一个目录结点(也就是根目录)从哪里来呢?
每一个文件系统的实例中都有一个super_block(超级块),这就是该文件系统实例的源头。super_block里面主要有如下信息:根目录inode结点的结点号、inode号与块的对应信息、块的分配信息(总共有多少块、哪些已使用、等等)。
利用inode号与块的对应信息,就能知道一个结点号所对应的inode保存在什么地方。(这种对应信息也可以是某种约定,比如号码为N的inode,存放在M*N块上。)
通过super_block中的根目录inode号,在文件系统被挂载时就能得到其根目录结点。(根目录inode号也可以是具体文件系统约定的,比如约定1号inode就是根目录。)
此外,一个文件被创建之后,其大小是随时可能改变的。利用super_block中记录的块的分配信息,就能在文件增大时为其分配新的块、在文件减小只回 收已经不需要使用的块。(这些信息并不是直接存放在super_block中,但是可以通过super_block找到它们,或者作为某种约定。比如约定 super_block之后的块是某种结构化信息,块的分配信息就保存于其中。)

那么,这个super_block又从哪里来呢?这一般就只能是约定的了(比如约定第0个块就是super_block)。
我们知道,在使用一个磁盘之前,需要将它格式化一下,格式化成某种具体文件系统所支持的格式。这就包括在磁盘上生成super_block、根目录inode、以及一些必要的文件。并且按照该文件系统的约定,正确摆放它们的位置。

最后,以上提到的块号,实际上都是虚拟的块号。当一块磁盘被划分成若干分区时,每个分区都被当作一个设备,都拥有各自独立的块号。所以,如果 super_block固定存放在0号块上,那么同一磁盘的分区0和分区1都有自己的0号块(它们分别对应到实际磁盘的两个不同的块上),从而都有自己的 super_block。

块的缓存
在《linux文件读写浅析 》中提到,存在一个磁盘高速缓存层,把文件的内容缓存在内存中。那么,文件内容以外的信息(比如inode)存在类似的缓存吗?

在linux上,设备也被当作是文件。读一个磁盘设备文件,能够读出磁盘上的原始数据。这些原始数据是什么呢?里面有super_block、 inode、文件内容、还有一些脏数据(它们一般被文件系统理解为空闲空间)。同样,磁盘设备文件也像普通文件一样,拥有与之对应的磁盘高速缓存。当内核 需要读磁盘上的某某块时(比如想读出存储在某块上的inode),实际上也是先在这个磁盘高速缓存上去寻找对应的内容,如果找不到再发起磁盘请求,并在读 取到数据后更新磁盘高速缓存。
然而,类似inode的块读写与文件内容的读写还是不大一样。文件内容是连续的,具体文件系统在将文件内容存储在磁盘上时,也会尽量分配连续的块。这样, 一次磁盘DMA,就可以读取若干个块,有益于效率。但像inode这样的东西却是孤立的,如果N号块是一个inode,N+1号块则很可能与之毫不相干。 对一个inode的读写基本上是针对一个块的,不需要拥有像文件内容缓存那样的预读特性。
这两种缓存有着不同的名字,文件内容的缓存叫cache,inode之类的块缓存叫buffer(在linux下查看内存使用情况时,一般会分别看到buffer和cache的大小)。

在磁盘高速缓存中,缓存的单位是页(因为缓存是内存)。而一个内存页的大小往往是块大小的若干倍(常见值是:page为4K、block为1K),所以需 要在磁盘高速缓存的内存页上再做一些细分,才能精确到块。在作为磁盘高速缓存页面的page结构上,附加buffer_head信息,如图(摘自 《ULK3》):

然后,在向通用块层发起磁盘读写请求时(参见《linux文件读写浅析 》),bio的构造将是基于buffer_head的(而对于文件内容的读写,bio基于page来构造)。

分享到:
评论

相关推荐

    linux文件系统实现浅析

    本文将深入分析Linux文件系统实现的一些关键概念和技术,特别是inode和super_block的角色。 首先,inode(索引节点)是文件系统中每个文件或目录的关键数据结构,它包含了关于文件的各种元数据,如文件的所有者...

    Linux下文件系统实现浅析.pdf

    Linux文件系统在硬盘上的结构通常包括引导块、超级块、索引节点、目录项和文件对象。引导块仅存在于根文件系统中,而超级块则包含了整个文件系统的信息。索引节点对象存储了关于文件的一般信息,如文件大小、权限等...

    浅析Linux文件系统管理.pdf

    本文主要探讨了在Red Hat 9.0环境下Linux文件系统的管理,包括磁盘管理的各个方面。 1. Linux 文件系统类型 Linux 支持多种文件系统,如ext2、ext3和ext4,其中Red Hat 9.0默认使用ext3文件系统。ext3是一种日志...

    浅析Linux的文件系统和磁盘管理.pdf

    浅析Linux的文件系统和磁盘管理 Linux操作系统的文件系统是存储和管理文件的方法,所有的软硬件资源全部看做文件。文件系统是操作系统的基本结构,因几乎所有与用户、应用程序或安全性模型的沟通方法都与文件保存的...

    Linux内核配置系统浅析

    ### Linux内核配置系统浅析 #### 一、配置系统的重要性及基本结构 随着Linux操作系统在各个领域的广泛应用,尤其是在嵌入式系统领域的迅速发展,越来越多的技术人员投身于Linux内核级别的开发工作。对于这些开发者...

    -Linux内核配置系统浅析.doc

    总之,Linux内核配置系统是一个灵活且强大的框架,允许开发者根据具体需求定制内核,以实现最佳性能和资源利用。理解和掌握这一系统是进行Linux内核开发的基础,也是提升Linux系统性能和可靠性的关键。

    Linux操作系统安全策略浅析.pdf

    《Linux操作系统安全策略浅析》一文探讨了在Linux环境下如何实施有效的安全策略,以保障系统的稳定和数据的安全。文章主要涉及以下几个方面: 1. **多系统共存的初步安装规划**:考虑到许多用户习惯使用Windows和...

    浅析基于Linux的数据库集群系统.pdf

    【标题】:“浅析基于Linux的数据库集群系统” 【描述】:本文探讨了在Linux操作系统上构建数据库集群系统的设计与实现,强调了Linux系统的特性及其在数据库集群中的应用。 【标签】:Linux操作系统、系统开发、...

    浅析Linux环境下文件I_O操作.pdf

    文章首先介绍了Linux环境中的文件系统调用,如create、open、close、read、write、lseek等,这些调用用于创建、打开、关闭文件,以及读取、写入和定位文件指针。文件描述符是Linux中用于标识文件的关键概念,它是一...

    浅析Linux的系统调用方法.pdf

    首先,系统调用是连接用户程序和内核的关键桥梁,允许用户应用程序使用操作系统提供的各种服务,如设备管理、文件系统操作、进程控制、进程通信和内存管理,而无需了解内核的具体实现。Linux系统调用分为三个层次:...

    浅析Linux的系统调用方法 (1).pdf

    《浅析Linux的系统调用方法》这篇文档主要探讨了Linux操作系统中系统调用的核心概念、数据结构和实现机制。系统调用是操作系统提供给应用程序访问底层硬件和服务的关键接口,它使得用户无需深入理解内核细节,即可...

    基于嵌入式Linux的运动检测系统设计浅析.docx

    接着移植和编译U-Boot以及Linux 2.6.33内核,构建基于busy-box 1.13.3的根文件系统。为了优化资源占用,系统需要对内核进行裁剪,同时编写运动检测应用程序和短信报警程序。 在运动目标检测算法上,通常有基于人工...

    浅析Linux中的core文件及调试方法

    在Linux操作系统中,core文件是当程序因某种错误崩溃时,内核生成的一种特殊文件,它包含了程序崩溃时的内存映像和调试信息。这对于排查和解决程序中的错误,特别是像“段错误”这样的运行时错误,是非常有价值的。...

Global site tag (gtag.js) - Google Analytics