如何理解linux的inode

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解linux的inode相关的知识,希望对你有一定的参考价值。

看了很多关于inode的资料,理解inode对于理解linux文件系统非常重要,并对于理解软硬链接及文件存储方式很有帮助,我结合了网上的资料及我自己学到的知识,总结了inode的一些基本知识,作为学习的笔记。

文件系统

??磁盘存储文件一盘是以扇区为单位,每个扇区为512字节,操作系统读取硬盘时不是一个一扇区读取,而是一次读取多个扇区,多个扇区划分成一个“块”(block),linux以块为单位存储数据,一般块的大小为4KB, 也就是8个扇区组成一个块。
??文件数据都存在块中,那么关于文件信息存储在哪里,比如文件权限访问和修改时间等,我们称为inode,就是专门存放文件的元数据信息,一个分区中如下结构图
技术图片
??第一部分是引导扇区,负责加载内核;第二部分是superblock,存储inode/block的总量、使用和剩余量及文件系统的信息;第三部分是inode,存储文件的元数据和数据所在的block号;第四部分是block,存储文件的数据。

什么是inode

??inode(index node)是linux和unix文件系统的一基本概念,inode在传统的类unix文件系统如ext3或ext4, linux扩展文件系统如ext2或ext3维护这个inode数据:inode表,每一个linux文件或目录(技术角度本质上没有什么区别),每个对象在文件系统中用一个inode表示, 但什么是对像?每一个文件在linux中有下列的结构:

  • 文件类型 (可执行,块设备等)
  • 权限(读,写, 执行等)
  • 所有者
  • 所有组
  • 文件尺寸
  • 时间戳:文件访问,(inode)改变和修改时间(记住linux不会记录文件建立时间,这在linxu运维中经常被问的问题)
  • 文件删除时间
  • 链接数量(软链接/硬链接)
  • 扩展属性(如immutable属性等)
  • 访问控制列表(ACLs)
  • 文件的位置的链接
  • 其它的matedate属性

?? 注意inode不存文件名字只存内容,所有以上信息都存在一个inode中,简而言之,inode就是标识文件或目录属性,每一个inode都有一个唯一的inode号,也称为index number.
下图为引用网上一张图,Ext2文件系统的inode结构图,由此计算可得block大小为4k时的单个文件的最大容量为4T
技术图片

??下图为文件系统的block、inode、目录项的指向情况:可以看到有两个目录项指向同一个inode,链接数会记录在inode中,只有当链接数为0时该文件才会被删除,也就是只有删除所有指向这个inode的文件名时才能删除文件
技术图片

如何检查inode

如果你想查看Ext文件系统中的inode, 可以使用一些命令查看其属性

  1. 显示文件数据信息
    你可以使用stat显示inode数据在一个文件或目录中, 你需要指定文件或目录的名称
[[email protected] data]# stat /etc/bashrc 
  File: ‘/etc/bashrc’
  Size: 2853            Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d      Inode: 3145765     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:etc_t:s0
Access: 2019-05-19 15:21:20.360016057 +0800
Modify: 2018-10-31 03:48:10.000000000 +0800
Change: 2019-05-16 22:14:01.457994270 +0800
 Birth: -

这个stat输出告诉你文件时间戳,所有者,权限和存储位置等,文件的数据存储在磁盘的块中,在stat中都可显示出来。
你可以只显示出inode number加--format选项输出

    #stat --format=%i /etc/bashrc    
    3145765
  1. 显示出文件的index number
    使用ls的-i选项可以显示出每个文件的inode number, 可以组合-l显示详细信息。
    #ls -il /etc
    total 1324
    3146085 -rw-r--r--.  1 root root     16 May 16 22:16 adjtime
    3145764 -rw-r--r--.  1 root root   1518 Jun  7  2013 aliases
    3148068 -rw-r--r--.  1 root root  12288 May 16 22:17 aliases.db
    3145741 drwxr-xr-x.  2 root root   4096 May 16 22:14 alternatives
    3146180 -rw-------.  1 root root    541 Apr 11  2018 anacrontab
    3145975 -rw-r--r--.  1 root root     55 Oct 30  2018 asound.conf
    3148004 drwxr-x---.  3 root root   4096 May 16 22:14 audisp
    3148009 drwxr-x---.  3 root root   4096 May 16 22:17 audit
    3145794 drwxr-xr-x.  2 root root   4096 May 16 22:14 bash_completion.d
    3145765 -rw-r--r--.  1 root root   2853 Oct 31  2018 bashrc
    3146020 drwxr-xr-x.  2 root root   4096 Oct 31  2018 binfmt.d
    3145851 -rw-r--r--.  1 root root     38 Nov 23 21:16 centos-release

第一列显示为inode number, 你可以显示出各别的文件的inode number

    #ls -i /etc/bashrc
    3145765 /etc/bashrc
  1. 显示出inode空间信息
    缺省情况下df只会描述磁盘的可用空间,你可以使用-i或--inodes选项列出inodes的可用空间
    #df -i
    Filesystem      Inodes IUsed   IFree IUse% Mounted on
    /dev/sda2      3276800 31335 3245465    1% /
    devtmpfs        252061   352  251709    1% /dev
    tmpfs           254731     1  254730    1% /dev/shm
    tmpfs           254731   591  254140    1% /run
    tmpfs           254731    16  254715    1% /sys/fs/cgroup
    /dev/sda1        65536   334   65202    1% /boot
    /dev/sda3      3276800    31 3276769    1% /data
    /dev/sr0             0     0       0     - /mnt/cdrom
    tmpfs           254731     1  254730    1% /run/user/0

这个信息非常有用,如果你的分区如果有很多非常小的文件,这会耗尽可用的inode空间但磁盘空间没有满。

  1. 可以使用tune2fs -l命令列出所有关于inode的信息
    #tune2fs -l /dev/sda1 | grep inode
    Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
    Free inodes:              65202
    First inode:              11
    Journal inode:            8
    Journal backup:           inode blocks

目录的inode结构

??如上所述,目录在linux中也是做一个文件来处理,目录是一个特别的文件,他是将文件名映射到inode number,也就目录条目或文件,当我们说目录包含文件或目录时,也就是说目录映射了这些目录和文件到它们的inode number, 这也说明为什么一个目录中不能有两个相同的名字,因为它不能映射一个名子到两个不同的inode number.

    # ls -ld /data
    drwxr-xr-x. 7 root root 4096 May 18 16:26 /data

当一个文件映射到他的父目录时,那么它的最顶级目录(如/目录)如何的呢?/目录的inode number是固定的,永远是2

#stat /
     File: ‘/’
     Size: 4096            Blocks: 8          IO Block: 4096   directory
     Device: 802h/2050d      Inode: 2           Links: 20
     Access: (0555/dr-xr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
     Context: system_u:object_r:root_t:s0
     Access: 2019-05-19 16:13:40.569926753 +0800
     Modify: 2019-05-16 23:03:45.731938337 +0800
     Change: 2019-05-16 23:03:45.731938337 +0800
     Birth: -

#stat /boot
    File: ‘/boot’
    Size: 4096            Blocks: 8          IO Block: 4096   directory
  Device: 801h/2049d      Inode: 2           Links: 6
  Access: (0555/dr-xr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
  Context: system_u:object_r:boot_t:s0
  Access: 2019-05-19 15:50:37.520966086 +0800
  Modify: 2019-05-16 22:17:31.300988303 +0800
  Change: 2019-05-16 22:17:31.300988303 +0800
  Birth: -

文件的链接

??链接和index number,在权限和所有者之间的数字是链接数量,链接数是指链接到这个文件的硬链接数,链接分为两种类型,软链接和硬链接。

  1. 软链接(或符号链接)
    软链接是一个分开的文件,他的内容是指向一个链接的文件,建立一个软链接使用ln -s,当使用这个命令时第一个参数为原始文件,第二个为你想要创建的链接文件。
#ln -s /home/bobbin/sync.sh filesync

文件filesync是一个软链接到sync.sh文件,可以想像成一个快捷方式,便捷filesync文件就是编辑原始的文件,如果你移动或删除了原始文件,那么filesync文件将不会再可用。
使用ls -l命令可以显示出文件是软链接文件,第一个字母为l并且有一个指定符>指向原始文件。

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

软链接的内容只是目标文件的名称,你可以看到软链接的权限完全打开的,因为权限不是它来管理的。
当你比较原始文件和软链接文件,它们有明显的区别

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

原始文件真接连接到inode, 但软链接指向它的名字,软链接文件很小它是参考引用文件名的字节数,因为没有其它信息可用在软链接文件中。

但注意在软链接建立时如果引用的是相于路径,那么要参考软链接文件位置的相于路径,不是参考原始文件的相对路径,否则你可以使用绝对路径。
列如我有目录:/data/test/test1, 原始文件为/date/1.sh, 将符号链接建立在/data/test/test1目录下,如果使用如下方法,产生的软链连将无法使用。

    [[email protected] data]#ln -s 1.sh test/test1/1link  
    [[email protected] data]#ll test/test1/1link 
    lrwxrwxrwx. 1 root root 4 May 19 17:07 test/test1/1link -> 1.sh  (会有红色闪烁表示不可用)

正确的方法是:

    [[email protected] data]#ln -s ../../1.sh test/test1/2link
    [[email protected] data]#ll test/test1/2link 
    lrwxrwxrwx. 1 root root 10 May 19 17:11 test/test1/2link -> ../../1.sh 
  1. 硬链接
    重要的理解就是inode number, 不是名字,一个硬链接是不同的名称但指向相同的inode number, 所以当你创建一个新的硬链接就相当于给inode增加了一个新的名字而已。
[[email protected] data]# ls -l 1.sh    
    -rwx------. 2 root root 0 May 18 15:53 1.sh
    [[email protected] data]# ln 1.sh test/test1/1hard
    [[email protected] data]# ll test/test1/1hard 
    -rwx------. 2 root root 0 May 18 15:53 test/test1/1hard

让我们比较一下这两个文件:

    [[email protected] data]# ll -il 1.sh test/test1/1hard 
    15 -rwx------. 2 root root 0 May 18 15:53 1.sh
    15 -rwx------. 2 root root 0 May 18 15:53 test/test1/1hard

这两个文件没有什么区别,除了名字不一样,你也可以注意到硬链接和软链接不同,它不是一个特殊的文件,它们的inode number都是15,指向了同一个文件,并且可以看到链接数都为2,但硬链接有两个局性:

  • 录不能做为硬链接,linux不充许这样维护循环目录树结构
  • 接不能跨文件系统,也就是说不同的分区,两个文件必在同一个文件系统, 因为不同的文件系统有不同的独立的inode表,比如相同的inode number的两个文件在不同的文件系统上是两个完全不同的文件,列如我有/data 和/boot, 这两个分区文件系统,如果我建立硬链接时会提示如下:
    [[email protected] data]# ln /boot/vmlinuz-3.10.0-957.el7.x86_64 /data/bootlinux
    ln: failed to create hard link ‘/data/bootlinux’ => ‘/boot/vmlinuz-3.10.0-957.el7.x86_64’: Invalid cross-device link

关于目录的链接数

上面说了,目录不能做为硬链接,但同学们有没有注意到,当你列目录时,目录的链接数最小是2,有的大于2。

[[email protected] data]# ll -id /data
2 drwxr-xr-x. 8 root root 4096 May 19 18:07 /data

因为在目录创建时本身下会自动创建有一个.和..的代表目录本身和上级目录,它的子文件夹下也会有你表目录本身和上级目录的.和..。

[[email protected] data]# ls -al /data
total 2344
drwxr-xr-x.  8 root root    4096 May 19 18:07 .
dr-xr-xr-x. 20 root root    4096 May 16 23:03 ..

所以文件夹中有几个子文件夹那么它的硬链接的个数就是子文件夹数量+2,如/data目录的inode number是8, 它下面就有6个子文件夹。

[[email protected] data]# ls -ild /data
2 drwxr-xr-x. 8 root root 4096 May 19 18:07 /data
[[email protected] data]# ls -ild /data/*/
1835009 drwxr-xr-x. 2 root root 4096 May 19 16:14 /data/aaaa/
1703937 drwxr-xr-x. 3 root root 4096 May 18 14:54 /data/app/
 917505 drwxrwxr-x. 4 root root 4096 May 19 17:58 /data/test/
3014657 drwxrws---. 2 root g1   4096 May 18 16:26 /data/testdir/
1048577 drwxr-sr-x. 2 root root 4096 May 18 16:17 /data/testsgid/
 262145 drwxr-xr-t. 2 root root 4096 May 18 16:23 /data/teststicky/

如何在linux中查找硬链接

你可以检索所有的文件名指向的inode number, 意思是你可以检索硬链接,因为它是指向相同内容(inode),你可以使用find带有-inum参数

[[email protected] data]# find / -inum 15
/sys/fs/selinux/checkreqprot
/sys/devices/platform/power
/sys/kernel/debug/boot_params/data
/data/1.sh
/data/test/test1/1hard
/boot/grub/splash.xpm.gz
/lib64

注意你要分清文件系统,不是同一个文件系统的文件是完全不同的文件,虽然inode number相同。

linux中与inode相关的操作

大多数的操作,如copy, 执行影响实际链接的文件(但mv,rm将会删除或移动软链接本身)

  1. copy文件
    当你copy一个文件,一个新的inode也会建立。
[[email protected] data]# cp test/test1/2link test
[[email protected] data]# ll -il 1.sh test/2link 
        15 -rwx------. 2 root root 0 May 18 15:53 1.sh
917513 -rwx------. 1 root root 0 May 19 17:47 test/2link

2link是1.sh的软链接文件,可见新的文件建立了自己的inode number

  1. mv文件
    当移动跨文件系统的文件时,也就是跨分区时,mv执行相当于cp命令,只是源文件是被删除的,但是当移动一个文件在同一个文件系统时,文件的inode number不会改变,只有目录下的inode映射会改变,实际的数据在硬盘上并没有移动。
    [[email protected] data]# ls -il samlefile.txt 
    18 -rw-r--r--. 1 root root 0 May 19 17:58 samlefile.txt
    [[email protected] data]# mv samlefile.txt test  
    [[email protected] data]# ls -il test/samlefile.txt
    18 -rw-r--r--. 1 root root 0 May 19 17:58 test/samlefile.txt
  1. 删除文件
    当执行rm时,第一步检查文件的链接数,如果链接数大于1,然后只是删除目录下的一条记录,并将链接数减1,数据仍然存在,inode也不受影响。但当链接数为1时,那么inode也会被删除, inode number变为可用,数据块占用的空间将会被划为可用空间块列表。
[[email protected] data]# ls -il samplefile.txt samplefile_hardlink.txt 
21 -rw-r--r--. 2 root root 15 May 19 18:06 samplefile_hardlink.txt
21 -rw-r--r--. 2 root root 15 May 19 18:06 samplefile.txt
[[email protected] data]# rm samplefile_hardlink.txt 
[[email protected] data]# ls -il samplefile.txt 
21 -rw-r--r--. 1 root root 15 May 19 18:06 samplefile.txt

你可以看到inode number减少为1

结论

??每一个linux文件都有一个inode, 并且inode包含文件的所有属性,但不是文件名称,软链接是指向原如文件的快捷方式,硬链接就像一个文件的复本,原文件和硬链接文件没什么不同,他们指定相同的inode.

以上是关于如何理解linux的inode的主要内容,如果未能解决你的问题,请参考以下文章

理解linux inode

理解inode

Linux深入理解重定向inode详解与软硬链接的概念及区别

Linux深入理解重定向inode详解与软硬链接的概念及区别

006_理解inode

理解inode