理解 Linux 中的 inodes

inodes 对于Linux是一个很重要的概念,它是 理解文件系统和磁盘存储的关键,理解了 inodes,常见的文件系统相关的问题就会迎刃而解,所以深入了解 inods 对于 Linux 从业者来说是非常有必要的

磁盘存储结构

安装操作系统或格式化磁盘分区的时候,操作系统会自动把磁盘分区分为两个区域 : Block存储区 和 inodes 存储区

Block存储区主要存储文件的内容

inodes存储区是由许多的inode组成的列表,每个 inode 中存储 文件元信息(文件大小,创建者,创建时间等)

以下是 磁盘分区中 Block存储区 和 inodes 存储区 图示:

inode 是什么

inode 是一种数据结构,用来存储文件以下的信息:

1、文件大小
2、文件类型(常规文件、目录、软连接等)
3、权限(读写执行权限)
4、属主(所属用户)
5、属组(所属用户组)
6、链接数(有多少个文件名指向这个inode)
7、文件创建时间
8、文件最近访问时间
9、文件最近修改时间
10、文件内容所在Block位置

可以通过以下命令查看文件的 inode 信息

[root@ecs-centos-7 ~]# stat t.txt 
  File: ‘t.txt’
  Size: 70              Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 2498227     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-07-19 16:50:14.370189948 +0800
Modify: 2020-07-19 16:50:12.302176601 +0800
Change: 2020-07-19 16:50:12.302176601 +0800
 Birth: -

inode 编号

每一个 inode 都有一个编号,系统根据 inode 编号可以快速的计算出 inode 信息在磁盘 inodes 存储区的偏移,然后从中获取 inode 信息,再根据 inode信息中记录的 Block 块位置,从Block存储区读出文件内容

inode 编号在一个文件系统中是唯一的,多个文件系统之间可能会出现相同的编号,前面的磁盘存储结构示意图中 /dev/vda1/dev/vda2 在各自的文件系统中 inode 编号是唯一的

创建一个新文件的时候,文件名和对应的 inode 编号会存储在目录文件的Block块中(关于目录文件后面会讲到)

文件的 inode 信息中记录了文件 Block 块的位置,Block块中存储着文件的内容,可以使用 ls -i 命令查看文件的 inode 编号

[root@ecs-centos-7 ~]# ls -i t.txt 
2498227 t.txt

inode 大小

下面的命令是查看每个 inode 节点的大小, 单位是字节

[root@ecs-centos-7 ~]# dumpe2fs -h /dev/vda1 | grep "Inode size"
dumpe2fs 1.42.9 (28-Dec-2013)
Inode size:               256

从例子中可以看出,每个 inode 节点大小为 256 字节。通过 df -i 命令可以查看每个文件系统中 inode 的使用情况

[root@ecs-centos-7 ~]# df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
devtmpfs        482393    339  482054    1% /dev
tmpfs           484984      1  484983    1% /dev/shm
tmpfs           484984    433  484551    1% /run
tmpfs           484984     16  484968    1% /sys/fs/cgroup
/dev/vda1      2621440 157202 2464238    6% /
tmpfs           484984      1  484983    1% /run/user/0

字段解释:

Filesystem:文件系统

Inodes: 文件系统中 inodes 总数量

IUsed: inodes 已经使用了的数量

IFree: inodes 可供使用的数量

IUse%: 已经使用了的 inodes 百分比

Mounted on: 文件系统的挂载点

文件系统中的 inodes 数量在安装系统或格式化磁盘分区的时候已经分配好了,也就是说 inodes 数量是有限的,所以 inodes 数量有可能耗尽的,耗尽之后就会出现磁盘还有空间,但是无法创建新文件的情况

目录文件

Linux 中所有的一切都是文件,包括进程、线程、目录等。每个文件都有对应的 inode 编号

当打开目录时,实际上是打开一个目录文件,目录的存储结构是目录子项列表,每个目录子项由 文件名、文件名对应的 inode 编号 组成

上图中是列出了 tmp/ 目录中所有文件,其中第一列是 inode 编号

红框中的 .表示当前目录,它是当前目录的一个硬链接,和当前目录拥有相同的inode编号。我们执行一个文件需要输入类似 ./test 的命令,命令中的 . 表示的就是当前目录

红框中的 ..表示当前目录的父目录,它是父目录的一个硬链接,和父目录拥有相同的inode编号。还记得返回上一层目录的命令 cd .. 吗?这里的.. 表示的就是当前目录的父目录

系统如何查看文件内容

tmp/ 目录中有 a.txt , b.txt, c.txt 三个文件, 其中 b.txt 是 a.txt 的硬链接,文件内容如下:

[root@ecs-centos-7 tmp]# cat a.txt 
this is a.txt file
[root@ecs-centos-7 tmp]# cat c.txt 
222

上面的图描述的是查看文件的流程,从图中可以看出 tmp/ 目录文件对应的 Block 块中存储的是该目录下文件名以及文件名对应的 inode 编号,而 a.txt、c.txt 文件对应的 Block 块中存储的是 a.txt 、c.txt 文件的内容

现以查看 a.txt 文件内容为例来说明在文件系统是如何查看文件内容的

1、根据 tmp/ 目录文件对应的 inode 编号(131098) 找到 tmp/ 目录文件对应 Block 数据块

2、从 tmp/ 目录文件对应的 Block 块中找出 a.txt 文件对应的 inode 编号(131101)

3、从 a.txt 文件对应的 inode 信息 中找到对应的 Block 块

4、读出 a.txt 文件对应的 Block 块中的数据(this is a.txt file)

通过 inode 查找文件

如果知道一个文件的 inode 编号,就可以使用以下的命令找到这个文件

[root@ecs-centos-7 ~]# find . -inum 2498227 
./t.txt

通过 inode 删除文件

知道了 inode 编号, 用下面的命令可以删除链接到此 inode 的文件

[root@ecs-centos-7 ~]# ls -i ta.txt 
2498227 ta.txt
[root@ecs-centos-7 ~]# find -inum 2498227
./ta.txt
[root@ecs-centos-7 ~]# find -inum 2498227 -delete
[root@ecs-centos-7 ~]# find -inum 2498227
[root@ecs-centos-7 ~]# 

上面的例子中, ta.txt 的 inode 编号是 2498227 ,当删除编号为 2498227 的文件后, ta.txt 文件被删除了

拷贝、重命名、移动文件

下面的命令分别对文件 ha.txt 进行拷贝,移动,重命名操作

[root@ecs-centos-7 ~]# ls -il ha.txt 
2498227 -rw-r--r-- 1 root root 6 Aug  1 01:12 ha.txt

[root@ecs-centos-7 ~]# cp ha.txt ha.txt.bak 
[root@ecs-centos-7 ~]# ls -il ha.txt*
2498227 -rw-r--r-- 1 root root 6 Aug  1 01:12 ha.txt
2498236 -rw-r--r-- 1 root root 6 Aug  1 01:13 ha.txt.bak

[root@ecs-centos-7 ~]# mv ha.txt haa.txt
[root@ecs-centos-7 ~]# ls -il haa.txt 
2498227 -rw-r--r-- 1 root root 6 Aug  1 01:12 haa.txt

[root@ecs-centos-7 ~]# mkdir testdir
[root@ecs-centos-7 ~]# mv haa.txt testdir/
[root@ecs-centos-7 ~]# ls -il testdir/haa.txt 
2498227 -rw-r--r-- 1 root root 6 Aug  1 01:12 testdir/haa.txt

上面的例子中 ha.txt 文件的inode初始编号是 2498227

cp拷贝: ha.txt 拷贝到 testdir/ha.txt 之后,
inode 编号变成 2498236

mv重命名: ha.txt 重命名成 haa.txt,haa.txt文件的 inode 编号和重命名之前的一样,是 2498227

mv移动:haa.txt 移动到 testdir/ 目录中
,移动之后 testdir/haa.txt 的inode 编号和移动之前一样,是 2498227

从上面的例子可以知道:拷贝命令会重新分配新的 inode, 改名以及移动文件只会修改文件名或文件位置,文件的 inode 并不会改变

posted @ 2020-08-04 23:54  Linux开发那些事儿  阅读(9576)  评论(0编辑  收藏  举报