(转)Linux文件系统的实现

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

Linux文件管理从用户的层面介绍了Linux管理文件的方式。Linux有一个树状结构来组织文件。树的顶端为根目录(/),节点为目录,而末端的叶子为包含数据的文件。当我们给出一个文件的完整路径时,我们从根目录出发,经过沿途各个目录,最终到达文件。

我们可以对文件进行许多操作,比如打开和读写。在Linux文件管理相关命令中,我们看到许多对文件进行操作的命令。它们大都基于对文件的打开和读写操作。比如cat可以打开文件,读取数据,最后在终端显示:

$cat test.txt

对于Linux下的程序员来说,了解文件系统的底层组织方式,是深入进行系统编程所必备的。即使是普通的Linux用户,也可以根据相关的内容,设计出更好的系统维护方案。

1 存储设备分区

文件系统的最终目的是把大量数据有组织的放入持久性(persistant)的存储设备中,比如硬盘和磁盘。这些存储设备与内存不同。它们的存储能力具有持久性,不会因为断电而消失;存储量大,但读取速度慢。

观察常见存储设备。最开始的区域是MBR,用于Linux开机启动(参考Linux开机启动)。剩余的空间可能分成数个分区(partition)。每个分区有一个相关的分区表(Partition table),记录分区的相关信息。这个分区表是储存在分区之外的。分区表说明了对应分区的起始位置和分区的大小。

我们在Windows系统常常看到C分区、D分区等。Linux系统下也可以有多个分区,但都被挂载在同一个文件系统树上。

数据被存入到某个分区中。一个典型的Linux分区(partition)包含有下面各个部分:

图 分区结构

分区的第一个部分是启动区(Boot block),它主要是为计算机开机服务的。Linux开机启动后,会首先载入MBR,随后MBR从某个硬盘的启动区加载程序。该程序负责进一步的操作系统的加载和启动。为了方便管理,即使某个分区中没有安装操作系统,Linux也会在该分区预留启动区。

启动区之后的是超级区(Super block)。它存储有文件系统的相关信息,包括文件系统的类型,inode的数目,数据块的数目。

随后是多个inodes,它们是实现文件存储的关键。在Linux系统中,一个文件可以分成几个数据块存储,就好像是分散在各地的龙珠一样。为了顺利的收集齐龙珠,我们需要一个“雷达”的指引:该文件对应的inode。每个文件对应一个inode。这个inode中包含多个指针,指向属于该文件各个数据块。当操作系统需要读取文件时,只需要对应inode的"地图",收集起分散的数据块,就可以收获我们的文件了。

最后一部分,就是真正储存数据的数据块们(data blocks)了。

Linux文件系统ext2主要分为三种类型的结构,superblock,inode,block。

superblock(超级块)

superblock记录了整个filesystem相关信息的地方,没有superblock,就没有filesystem

  • block与inode的总量
  • 未使用与已使用的inode/block数量
  • block与inode的大小
  • filesystem挂载时间,最近一次写入数据时间,最近一次检验磁盘时间等
  • 一个valid bit数值,若被挂载为0,否则为1

 inode

  • 文件的字节数
  • 文件拥有者的User ID
  • 文件的Group ID
  • 文件的读、写、执行权限
  • 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  • 链接数,即有多少文件名指向这个inode
  • 文件数据block的位置

 block

大小一般为1k,2k,4k,是真实存储数据内容的区域。

图分区结构为他们三者的关系,其中boot block大小为1k,super block大小为1k。

1.1 inode简介

上面我们看到了存储设备的宏观结构。我们要深入到分区的结构,特别是文件在分区中的存储方式。

文件是文件系统对数据的分割单元。文件系统用目录来组织文件,赋予文件以上下分级的结构。在硬盘上实现这一分级结构的关键,是使用inode来虚拟普通文件和目录文件对象。

Linux文件管理中,我们知道,一个文件除了自身的数据之外,还有一个附属信息,即文件的元数据(metadata)。这个元数据用于记录文件的许多信息,比如文件大小,拥有人,所属的组,修改日期等等。元数据并不包含在文件的数据中,而是由操作系统维护的。事实上,这个所谓的元数据就包含在inode中。我们可以用$ls -l filename来查看这些元数据。正如我们上面看到的,inode所占据的区域与数据块的区域不同。每个inode有一个唯一的整数编号(inode number)表示。

在保存元数据,inode是“文件”从抽象到具体的关键。正如上一节中提到的,inode储存由一些指针,这些指针指向存储设备中的一些数据块,文件的内容就储存在这些数据块中。当Linux想要打开一个文件时,只需要找到文件对应的inode,然后沿着指针,将所有的数据块收集起来,就可以在内存中组成一个文件的数据了。

数据块在1, 32, 0, ...

inode并不是组织文件的唯一方式。最简单的组织文件的方法,是把文件依次顺序的放入存储设备,DVD就采取了类似的方式。但如果有删除操作,删除造成的空余空间夹杂在正常文件之间,很难利用和管理。

复杂的方式可以使用链表,每个数据块都有一个指针,指向属于同一文件的下一个数据块。这样的好处是可以利用零散的空余空间,坏处是对文件的操作必须按照线性方式进行。如果想随机存取,那么必须遍历链表,直到目标位置。由于这一遍历不是在内存进行,所以速度很慢。

FAT系统是将上面链表的指针取出,放入到内存的一个数组中。这样,FAT可以根据内存的索引,迅速的找到一个文件。这样做的主要问题是,索引数组的大小与数据块的总数相同。因此,存储设备很大的话,这个索引数组会比较大。

inode既可以充分利用空间,在内存占据空间不与存储设备相关,解决了上面的问题。但inode也有自己的问题。每个inode能够存储的数据块指针总数是固定的。如果一个文件需要的数据块超过这一总数,inode需要额外的空间来存储多出来的指针。(不是很理解??)

1.2 inode示例

在Linux中,我们通过解析路径,根据沿途的目录文件来找到某个文件。目录中的条目除了所包含的文件名,还有对应的inode编号。当我们输入$cat /var/test.txt时,Linux将在根目录文件中找到var这个目录文件的inode编号,然后根据inode合成var的数据。随后,根据var中的记录,找到text.txt的inode编号,沿着inode中的指针,收集数据块,合成text.txt的数据。整个过程中,我们参考了三个inode:根目录文件,var目录文件,text.txt文件的inodes。

在Linux下,可以使用$stat filename,来查询某个文件对应的inode编号。

在存储设备中实际上存储为:

当我们读取一个文件时,实际上是在目录中找到了这个文件的inode编号,然后根据inode的指针,把数据块组合起来,放入内存供进一步的处理。当我们写入一个文件时,是分配一个空白inode给该文件,将其inode编号记入该文件所属的目录,然后选取空白的数据块,让inode的指针指像这些数据块,并放入内存中的数据。

2 文件共享

在Linux的进程中,当我们打开一个文件时,返回的是一个文件描述符。这个文件描述符是一个数组的下标,对应数组元素为一个指针。有趣的是,这个指针并没有直接指向文件的inode,而是指向了一个文件表格,再通过该表格,指向加载到内存中的目标文件的inode。如下图,一个进程打开了两个文件。

可以看到,每个文件表格中记录了文件打开的状态(status flags),比如只读,写入等,还记录了每个文件的当前读写位置(offset)。当有两个进程打开同一个文件时,可以有两个文件表格,每个文件表格对应的打开状态和当前位置不同,从而支持一些文件共享的操作,比如同时读取。

要注意的是进程fork之后的情况,子进程将只复制文件描述符的数组,而和父进程共享内核维护的文件表格和inode。此时要特别小心程序的编写。

3 总结

这里概括性的总结了Linux的文件系统。Linux以inode的方式,让数据形成文件。

了解Linux的文件系统,是深入了解操作系Linux原理的重要一步。

欢迎阅读Linux的概念与体系系列文章

时间: 2024-10-16 03:09:25

(转)Linux文件系统的实现的相关文章

linux 文件系统笔记

文件格式: windows:PE linux:  ELF 文件系统: rootfs FHS:规定linux应该创建哪些目录 /下的目录结构: /boot: 系统启动相关的文件,如内核,initrd,以及 grub(bootloader) /dev :设备文件(例如:光盘,cdrom) 类型: 块设备:随机访问, 数据块 字符设备:线性访问, 以字节为单位 设备号:主设备号(major),次设备号(minor) /etc:  配置文件(绝大多数为纯文本格式) /home: 用户的家目录,默认为/h

【转】LINUX文件系统剖析

引自:http://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/   在文件系统方面,Linux? 可以算得上操作系统中的 "瑞士军刀".Linux 支持许多种文件系统,从日志型文件系统到集群文件系统和加密文件系统.对于使用标准的和比较奇特的文件系统以及开发文件系统来说,Linux 是极好的平台.本文讨论 Linux 内核中的虚拟文件系统(VFS,有时候称为虚拟文件系统交换器),然后介绍将文件系统连接在一起的主要结构.

Linux文件系统

文件系统与目录结构 文件系统 1.文件和目录被组织成一个单根倒置数结构 2.文件系统从根目录下开始,用"/"表示 3.根文件系统(rootfs):root filesystem 4.文件名称区分大小写 5.以.开头的文件为隐藏文件 6.路径分隔符:/ 7.文件的两类数据: 元数据(metadata)和 数据(data) 8.文件系统分层结构:LSB (Linux Standard Base) 9.FHS(Filesystem Hierarchy System) 文件名规则 1.文件名最

linux文件系统索引节点浅析

索引节点,Inode是Index Node的缩写,存储于文件系统上的任何文件都可以用索引节点来表示,所以也可以说索引节点是整个linux文件系统的基础.操作系统在读取硬盘的时候不是一个块一个块的来读取信息,因为这样做的话效率太低,文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者.文件的创建日期.文件的大小等等.这种储存文件元信息的区域就叫做inode,中文译名为"索引节点". 在Linux系统中,文件系统主要分为两部分,

嵌入式 Linux根文件系统移植(一)——Linux文件系统简介

嵌入式 Linux根文件系统移植(一)--Linux文件系统简介 本文对文件系统分析的代码来源于linux 2.6.35.7版本. 一.文件系统的体系结构 文件系统是对存储设备上的数据和元数据进行组织的机制,便于用户和操作系统的交互.Linux支持多种文件系统,文件系统接口实现为分层的体系结构,将用户接口层.文件系统实现和操作存储设备的驱动程序分隔开.Linux文件系统的体系结构如下: 用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C库(glibc),为文件系统调用(打开.读取.

linux --> 文件系统十问

文件系统十问 参考:http://djt.qq.com/article/view/620 关于Linux文件系统相关的问题: 1.机械磁盘随机读写时速度非常慢,操作系统是采用什么技巧来提高随机读写的性能的? 2.touch一个新的空文件占用磁盘空间吗? 占用的话占用多少? 3.新建一个空目录占用磁盘空间吗?占用多少?和新建一个文件相比,哪个占用的更大? 4.你知道文件名是记录在磁盘的什么地方吗? 5.文件名最长多长?受什么制约? 6.文件名太长了会影响系统性能吗?为什么会产生影响? 7.一个目录

linux文件系统学习总结

linux最优秀的特点在于它是多用户多任务的环境,而且对于linux来讲一切皆文件,提到文件这个概念就免不了提文件相关的权限与属性的概念,那相关文件的属性记录在硬盘的哪个地方呢?这就需要了解linux的文件系统是如何记录文件,如何读取文件. 大家都知道硬盘作为存储介质,如果要使用硬盘存储数据需要对硬盘进行分区,格式化之后才可以存储数据.那为什么要对硬盘进行分区呢?因为我们必须要告诉操作系统:"这块硬盘可以访问的区域是有A柱面到B柱面",只有这样,操作系统才能控制硬盘磁头去A~B范围内的

Vim,find,bash,Linux文件系统的特殊权限2015.8.30作业

一   Vim 1.vim的使用方法 1.1 三种模式化 编辑模式.输入模式.末行模式 1.2 模式转换 编辑模式 --> 输入模式: i:在当前光标所在字符的前面,转为输入模式 a:在当前光标所在字符的后面,转为输入模式 o:在当前光标所在行的下方,新建一行,并转为输入模式 I:在当前光标所在行的行首,转为输入模式 A:在当前光标所在行的行尾,转为输入模式 O:在当前光标所在行的上方,新建一行,并转为输入模式 输入模式 --> 编辑模式:ESC 编辑模式 --> 末行模式:: 末行模式

攻城狮在路上(叁)Linux(二十六)--- linux文件系统的特殊查看与操作

一.boot sector 与 super block的关系: 1.boot sector用于存放引导装载程序,占用1024个字节. 2.super block的大小也为1024字节. 3.若block大小为1k,则boot sector和super block各占一个block. 4.若block大于1K(2K/4K)时,则两者都位于第一个block中. 二.磁盘空间的浪费问题:暂不考虑. 三.利用GUN的parted命令进行分区行为: 因为fdisk不支持高于2TB的分区. 命令格式: pa

操作系统——linux文件系统初实现——为fileSystem添加驱动,让linux可以识别。

0.我的理解,所为驱动,就是用户可以通过自己的应用程序访问你的文件系统.而我恰恰相反. 1.我是谢了字符驱动,让我的fileSystem去做应用程序,同样可以被linux系统识别. 2.其实我对驱动理解也不深,暂且贴代码. 3.驱动程序: /*chardev.c 驱动程序*/ #include <linux/kernel.h> #include <linux/fs.h>/*for file-f_op*/ #include <linux/module.h> #includ