详解Linux Inode

一切都是文件,Linux和其他类Unix操作系统通过将所有内容都视为文件(甚至是硬件设备)来保持一致性。 键盘,鼠标,打印机,显示器,硬盘,进程,甚至目录都被视为Linux中的文件。 常规文件包含文本(文本文件),音乐,视频(多媒体文件)等数据。除常规数据外,还有一些关于这些文件的其他数据,例如它们的大小,所有权,权限,时间戳等。 有关文件的元数据使用称为inode(索引节点)的数据结构进行管理。

什么是 inode?

每个Linux文件或目录 (从技术角度讲,它们之间没有本质的区别) 都有一个inode,而这个inode包含了所有文件的元数据 (也就是说,读取文件所需的管理数据都存储在inode中)。例如,inode包含存储文件的所有块的列表,该文件所有者信息、权限以及为该文件设置的所有其他属性。从某种意义上讲,你可以说文件就是inode,并且文件名被附加到inode上以使人们更容易使用它们。

inode在文件系统创建是确定,并且每个文件系统都有一个inode集合。最大的目录大小取决于不同的文件系统。为了获得更好的性能,通常将文件放入不同的子目录中,而不是将所有文件放入同一个目录。

什么是inode number

inode是inode table中的一个条目,包含有关目录和常规文件的元数据。inode是传统Unix风格文件系统 (比如ext3/ext4) 上的数据结构。Linux扩展文件系统 (如ext2/ext3) 维护了一个inode的数组:inode table。inode table包含该文件系统中所有文件的列表。inode table中的各个inode项具有唯一的编号 (该文件系统唯一),即inode number。深入inode数据结构,我们发现它存储了如下信息:

  • 文件类型: 普通文件,目录,管道等等
  • 权限:可读,可写,可执行
  • 链接数:链接到该inode的硬链接数
  • User ID:文件所有者
  • Group ID:所有者组ID
  • 文件大小
  • 时间信息
  • 属性:比如,不可改变位
  • 访问控制列表
  • 文件数据存储的实际位置
  • 其他元数据

注意:inode中不存储文件名数据

如何查看inode信息

如果你希望查看文件系统的inode信息,你可以使用一些shell命令来查看文件系统的属性

a. 显示指定文件信息

你可以使用stat命令显示某个文件或目录的inode信息,你必须指定文件或目录名

# stat log.txt
  File: 'log.txt'
  Size: 212             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 591912      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-11-26 11:27:13.683598803 +0800
Modify: 2018-12-06 17:18:49.799424595 +0800
Change: 2018-12-06 17:18:49.799424595 +0800
 Birth: -

命令的输出告诉了你该文件的各种时间信息,它的所有权和权限,以及文件存储的位置。存储文件数据的磁盘块信息也展示在stat命令的输出中。

你也可以选择只列出文件的inode number:

# stat --format=%i log.txt
591912
b. 打印文件的inode number

ls命令用于列出文件/文件夹的信息。参数 -i 说明需要显示每个文件的inode number。我们可以结合参数 -l 一起使用以列出详细信息:

# ls -li
total 16
592404 drwxr-xr-x 6 root root 4096 Nov  2 15:01 config
591900 -rw-r--r-- 1 root root  453 Nov 25 22:25 docker-compose-single.yml
592414 -rw-r--r-- 1 root root 2714 Nov  2 15:01 docker-compose.yml
592415 drwxr-xr-x 2 root root 4096 Nov  2 15:01 mariadb

输出的第一列显示了文件的inode number。

c. 显示文件系统inode的使用信息

默认情况下,df命令汇总可用和已用的磁盘空间。你可以通过传递 -i--inodes 选项来接收有关可用和已使用的inode报告。

# df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
udev           2032387    398 2031989    1% /dev
tmpfs          2037595   1224 2036371    1% /run
/dev/vda1      3276800 325180 2951620   10% /
tmpfs          2037595      7 2037588    1% /dev/shm
tmpfs          2037595      4 2037591    1% /run/lock
tmpfs          2037595     16 2037579    1% /sys/fs/cgroup
overlay        3276800 325180 2951620   10% /var/lib/docker/overlay2/c1955f95c338497d2f669ee0baf2706f93c2765001cafd3568b5af9ebfbe0dfd/merged
overlay        3276800 325180 2951620   10% /var/lib/docker/overlay2/85a6ee4a64760a9e52efa312094092121160030132aaaf4bd32ecf5585324dfd/merged
overlay        3276800 325180 2951620   10% /var/lib/docker/overlay2/692ed70766a4ee954c0f0f1b19d69b906c33ae54a618f8686f66e31e9ac05606/merged
shm            2037595      1 2037594    1% /var/lib/docker/containers/2a09d78972ebb74a7631dfd5e567a2b54282886ac8d8dc54dc1f5badffc692b8/mounts/shm
shm            2037595      1 2037594    1% /var/lib/docker/containers/fd9619309707c1026876a401ac22eaf8dd9bfbaceb237ee927017818a6ffa3ff/mounts/shm
shm            2037595      1 2037594    1% /var/lib/docker/containers/080d0d79e069041a2997dfaf2c07e69a0518ad44271dad4688f459958dac09c5/mounts/shm
tmpfs          2037595      4 2037591    1% /run/user/1000

如果分区包含很多小文件,这些信息可能会有帮助,这可能会比耗尽可用磁盘空间更快的耗尽可用的inode。

d. 列出文件系统超级块的信息

你可以使用 tune2fs -l 命令来显示所有与inode相关的信息。

# tune2fs -l /dev/vda1  | grep inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent sparse_super large_file uninit_bg
Free inodes:              2952348
First inode:              11
Journal inode:            8
First orphan inode:       221187
Journal backup:           inode blocks

目录的inode结构

上面提到过,Linux中的目录也被视为文件。目录是将文件名映射到其inode number的特殊文件 (此映射称为dentry)。因此,当我们说某个目录包含文件和其他目录时,我们的意思是该目录将这些文件和目录映射到它们的inode number。这就是目录无法容纳两个具有相同名称的文件的原因,因为它无法使用两个不同的inode number映射一个名称。

当一个文件通过其父目录映射到它到inode时,那么最顶层的目录(即 / 目录)如何映射到它的inode?实际上,/ 目录的inode number是固定的,始终为2。

# stat /
File: '/'
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fd01h/64769d    Inode: 2           Links: 24
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-07-24 17:05:52.740982553 +0800
Modify: 2018-12-21 18:02:05.258315357 +0800
Change: 2018-12-21 18:02:05.258315357 +0800
 Birth: -

链接

在命令 ls -l 的输出中,权限之后和所有者之前的列是链接计数。 链接计数是指文件的硬链接数。 要理解硬链接,我们从链接开始。 链接是指向另一个文件的指针。 在Linux世界中,存在两种类型的链接:

a. 符号链接 (软链接)

符号链接是一个单独的文件,其内容指向被链接的文件。 要创建符号链接,请使用带有-s选项的ln命令。 使用ln命令时,请确保首先引用原始文件的名称,然后引用要创建的链接的名称。

# ln -s /home/opt/sync.sh filesync

这里filesync是sync.sh的符号链接。 把它想象成一个快捷方式。 编辑filesync就像直接编辑原始文件一样。 如果我们删除或移动原始文件,链接将被破坏,我们的filesync文件将不再可用。

ls -l 命令显示生成的文件是符号链接。 这由 ls -l 输出的第一个位置中的字母l以及列表末尾的箭头指示,该箭头表示链接所指向的文件。

# ls -l filesync 
lrwxrwxrwx 1 root root 20 Apr 7 06:08 filesync -> /home/opt/sync.sh

比较符号链接和原始文件时,您会发现它们之间存在明显差异。

# ls -il /home/opt/sync.sh filesync 
258674 lrwxrwxrwx 1 root root 20 Apr 7 06:08 filesync -> /home/opt/sync.sh
517333 -rw-r----- 1 root root 5 Apr 7 06:09 /home/opt/sync.sh

原始文件只是一个直接连接到inode的文件,而符号链接指向该文件。 符号链接的大小是它引用的文件名称的字节数,因为符号链接中没有其他信息可用。

b. 硬链接

要了解硬链接是什么,关键是要了解文件的标识是其inode编号,而不是其名称。 硬链接是一个引用inode的名称。 这意味着如果file1有一个名为file2的硬链接,那么这两个文件都引用相同的inode。 因此,当您为文件创建硬链接时,您真正要做的就是为inode添加一个新名称。 为此,请使用不带选项的ln命令。

# ls -l /home/opt/sync.sh  
-rw-r----- 1 root root 5 Apr 7 06:09 /home/bobbin/sync.sh
# ln /home/opt/sync.sh synchro

让我们来比较这两个文件

# ls -il /home/bobbin/sync.sh synchro 
517333 -rw-r----- 2 root root 5 Apr 7 06:09 /home/opt/sync.sh
517333 -rw-r----- 2 root root 5 Apr 7 06:09 synchro

关于硬链接的有趣之处在于原始文件和链接之间没有区别:它们只是连接到同一个inode的两个名称。

正如您必须注意到的,与软链接不同,硬链接不是特殊文件。 现在,链接计数是文件硬链接的数字。 因此,创建硬链接后链接计数会增加,如上图所示。 这些硬链接有两个限制:

  • 目录不能硬链接。 Linux不允许这样做以维护目录的非循环树结构。
  • 无法跨文件系统创建硬链接。 这两个文件必须位于相同的文件系统上,因为不同的文件系统具有不同的独立inode表(不同文件系统上具有相同inode编号的两个文件是不同的)。

结论

每个Linux文件都有一个inode数据结构,inode包含文件的所有属性,但不包含文件名。 符号链接类似于指向原始文件的快捷方式,而硬链接类似于文件的一份拷贝。 原始文件和硬链接之间没有区别,他们都引用同一个inode。

你可能感兴趣的:(详解Linux Inode)