24

Linux 文件系统 -- inode 笔记

 4 years ago
source link: http://www.cnblogs.com/chenxinshuo/p/12150645.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

什么是 inode

inode 的定义:Unix 文件系统中的一种数据结构,用来存储文件的元信息数据

文件在硬盘中的存储是以"块"(block)为单位的,常见的块大小是 4k

一个稍微大一点的文件则会存储在多个块中,那么如何快速访问到这些数据呢?答案就是 inode

在文件系统中,每个文件对象都对应着一个 inode,其中存储着常用的一些信息(所有者、创建时间、修改时间、文件权限、对应文件对象在系统中存储块的位置等等)

操作系统访问一个文件时分为三个步骤:

  1. 通过文件名找到对应的 inode 编号
  2. 通过 inode 编号访问对应文件对象的元信息
  3. 根据元信息找到文件对应的 block,读取数据

从上面的描述可以看出,inode 实际上就是文件系统中的一种索引,便于管理文件以及快速访问数据

关于 inode 的一些细节

inode 的内容

POSIX 标准定义了 inode 所包含的信息:

  • 以字节为单位表示的文件大小
  • 设备ID,标识容纳该文件的设备
  • 文件所有者的 User ID
  • 文件的 Group ID
  • 文件的模式(mode),确定了文件的类型,以及它的所有者、它的 group、其它用户访问此文件的权限
  • 额外的系统与用户标志(flag),用来保护该文件
  • 3 个时间戳,记录了 inode 自身被修改(ctime, inode change time)、文件内容被修改(mtime, modification time)、最后一次访问(atime, access time)的时间
  • 1 个链接数,表示有多少个硬链接指向此inode
  • 指向文件系统存储位置的指针

使用 stat 命令可以查询一个文件的 inode 编号及对应的文件元信息:

ryEJbiN.png!web

inode 的存储

inode 存储文件对象的元信息,也会占用一部分磁盘空间

当文件系统创建(格式化)时,会把存储区域分为两大连续的区域,其中一个用来保存 inode,称为 inode table,每个 inode 默认 128 or 256 字节

另一块区域则用来保存文件的数据块

从这里可以看出,一个文件系统中 inode 的数量在初始化时确定了,inode 的数量和磁盘大小成正比

查看每个硬盘分区的 inode 总数和已经使用的数量,可以使用 df 命令:

jyE3EvF.png!web

由于每个文件都会对应一个 inode,当磁盘中存在大量小文件时,就可能出现磁盘空间有空闲但是 inode 用完的情况

例如一个电子邮件服务器可能会存在大量 eml 文件使磁盘 inode 耗尽,无法入信新邮件

所以一般大型的邮件系统都会设计自己的文件系统来存储邮件数据,如使用信桶(mbox)文件结构来存储单个用户的所有邮件数据

目录文件、硬链接和软链接

Linux 中一切皆文件,目录也是文件的一种,每个目录项包含两部分:目录中所有文件的文件名、所有文件名对应的 inode 编号

使用 ls -i 命令查看目录的内容:

Qry6JvI.png!web

如果想要查看该目录下文件的详细信息,那么就需要根据每个文件的 inode 编号,找到对应的 inode 访问元信息:

2mEZZjZ.png!web

上述 inode 中包含的信息中,可以发现并不存在文件名这一信息,实际上在 Unix 环境下,一个文件对象可以对应多个文件名,即硬链接(hard link)

使用 ln 命令可以创建硬链接:

ln 源文件 目标文件
juiIRf3.png!web

上图中 f1.txt f2.txt 都指向同一个 inode,修改其中一个文件内容会影响到另一个

从 inode 内容中可以发现有一个链接数,当我们创建了一个硬链接时,所对应的文件的 inode 中链接数就会 +1,表示其对应的文件名(引用计数)+1

同理,当删除一个文件后,该链接数将 -1,链接数为 0 时文件数据就被完全清除了

与硬链接对应的还有软链接,使用 ln -s 命令可以创建软链接:

ln -s 源文文件或目录 目标文件或目录
M7j6BnN.png!web

软链接和硬链接的区别在于,软链接指向其链接的文件名,而不是 inode,一个软链接有自己的 inode

删除其指向的文件后,该软链接则不可访问(No such file or directory)

这里的设计类似于 C++ 中指针和引用,硬链接可以类比为引用,而软链接则是指针,其中保存着文件名(访问文件数据的地址)

而 inode 链接数则和智能指针的引用计数设计思路相似,不得不说计算机系统中很多设计都有共通性

inode 的其他作用

由于硬链接的存在,文件名和 inode 是多对一的关系,操作系统打开一个文件后就抛弃了文件名,只保留 inode 编号来访问文件内容

库函数 getcwd() 的实现,就是从当前工作目录的 inode 逐级查找上级目录的 inode,最后拼出完整的绝对路径

inode 的设计,使得在操作系统中安装/更换新的库文件十分方便

当一些进程还在使用库时,其他进程可以替换该库文件 inode 编号指向新创建的 inode,后面对该库的访问都被引导至新库文件的内容,减少了替换库时重启系统的必要

由于旧的 inode 中链接数已经为 0,在使用旧库的进程结束后,旧的 inode 和旧库文件将被文件系统自动回收

参考文献


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK