在理解inode之前,先了解下磁盘扇区,磁盘的最小单位,我们都知道,磁盘一个扇区是512个字节。磁盘读写是都是按照块来操作的,一个块一般是4K,也就是连续的8个扇区,以块为单位读写是为了提高性能。

文件数据都储存在”块”中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。

磁盘上inode节点存储数据“块”存储是在两个不同的区域,inode存储文件的元数据,但是不包括变长的文件名信息,因此inode大小是固定的,包含的元数据如下:

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

可以使用 stat file_name 查看文件的inode数据,硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

因此,对于存储大量小文件来说,可能文件系统的inode不够用,如果inode资源耗尽,就无法新建文件。比如阿里的TFS(专门用于存储小文件的分布式存储)就是将小文件合并成“大块”文件来存储的,节省inode资源。

可以使用 df -i 查看各个分区的Inode使用情况:

1
2
3
4
5
6
7
8
9
[luoxn28@localhost ~]$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda3 9283072 297711 8985361 4% /
devtmpfs 180632 384 180248 1% /dev
tmpfs 184648 1 184647 1% /dev/shm
tmpfs 184648 914 183734 1% /run
tmpfs 184648 16 184632 1% /sys/fs/cgroup
/dev/sda1 153600 334 153266 1% /boot
tmpfs 184648 20 184628 1% /run/user/1000

innode号码

每个inode都有一个号码,操作系统用inode号码来识别不同的文件。Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。

表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。使用*ls -i file_name*命令可以查看inode号码。

目录文件

目录也是一种文件,也有自己的inode,其inode本身存储该目录的元信息,对应的块内容存储一系列文件(目录+文件),每个文件包括文件名及其对应的inode编号。

硬链接与软连接

硬链接和软连接都是对应同一个文件块,只不过:

  • 硬链接:两个文件名对应同一个inode节点,只不过inode节点的连接数为2,删除其中一个硬链接时不会真正删除文件,只有在inode连接数为0时才会删除文件;
  • 软连接:两个文件名分别对应各自的inode节点,这两个inode节点指向同一个文件块,通过原来文件名删除文件后,建立的软连接无法使用了,软连接类似于windows的快捷方式。