VFS 虚拟文件系统

说明

  • 硬盘block:硬盘的最小存储单位是"扇区"(Sector),每个扇区512个字节,操作系统操作硬盘时,为了加快效率,将多个连续扇区合并管理,即一次性操作多个扇区,称为一"块"(block),"块"是文件操作的最小单位,最常见的块大小是4KB,即连续八个sector组成一个block。

数据划分

  • linux系统把数据分为以下三部分,分别进行管理。
  1. 文件数据(内容数据)
  2. 文件信息,也叫元信息,包含文件创建者、创建日期、大小等信息,储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
  3. 目录结构(目录树形结构),在linux系统为dentry。

文件数据

  • 文件数据比较容易理解,就是文件中保存的数据内容。

文件信息(inode)

  • inode包含文件的元信息,有以下内容:
  1. 文件的字节数
  2. 文件拥有者的User ID
  3. 文件的Group ID
  4. 文件的读、写、执行权限
  5. 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  6. 链接数,即有多少文件名指向这个inode
  7. 文件数据所在block的编号,使用数组存储,block可以是非连续的,不然文件大小无法动态调整,但是不同文件系统,数组大小可能不同,因此支持的文件大小也被其限制。
  • 可以用stat命令,查看某个文件的inode信息:
stat example.txt
  • 但是inode中不包含文件名。

inode 大小

  • 由于保存的数据是固定的,因此每个inode节点的大小也是固定的,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。
  • 假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。
  • 查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令。
df -i
  • 查看每个inode节点的大小,可以用如下命令:
sudo dumpe2fs -h /dev/hda | grep "Inode size"
  • 由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。

inode 编号

  • 每个inode节点都有一个编号,操作系统内部使用编号来操作不同的文件,而不是通过文件名。
  • 使用ls -i命令,可以看到文件名对应的inode号码:
ls -i example.txt
  • inode编号可能就是序号,例如:第一个inode节点,第二个inode节点,因此系统可以通过该编号和inode大小计算出偏移来定位到硬盘上的inode数据。

目录结构(dentry)

  • 每个目录对应一个dentry节点。
  • 目录文件的结构比较简单,就是子文件和子目录列表;每个目录项,主要由两部分组成:
  1. 文件名。
  2. 该文件对应的inode号码。
  • ls命令只列出目录文件中的所有文件名:
ls /etc
  • ls -i命令列出整个目录文件,即文件名和inode号码:
ls -i /etc
  • 如果要查看文件的详细信息,就必须根据inode号码,访问inode节点,读取信息。ls -l命令列出文件的详细信息。
ls -l /etc

存储形态

  • 文件数据和文件信息都会保存在硬盘上,操作系统会将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。
  • linux并没有使用单独的硬盘区域来保存目录结构数据,因为其将每个目录当做特殊的文件存储,每个目录文件也有对应的inode节点。

内存形态

  • 在内存中,inode, dentry和文件数据都会进行缓存。
  • 每个文件和目录都需要一个inode和一个dentry空间,无法完全在内存中缓存这些数据,linux采用的是按需创建维护LRU(Least Recently Used)列表,释放掉没使用的dentry项与inode项。

读写流程

  • 文件系统如何读写文件的:
  1. 根据文件名,通过目录结构的对应关系,找到文件对应的Inode number
  • 通过文件名,根据保存在内存中的目录结构(dentry)缓存,进行查找其inode number,如果不在缓存中,则可通过根目录或者当前目录进行遍历访问。
  1. 再根据Inode number读取到文件的Inode table
  • 再根据inode number从硬盘inode区域中找到对应的inode节点,
  1. 再根据Inode table中的Pointer读取到相应的Blocks
  • 再根据inode节点中的block块编号,映射为地址偏移,访问其真正的文件内容数据

你可能感兴趣的:(#,Linux,内核知识)