如何理解linux的inode

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

文件系统

  磁盘存储文件一盘是以扇区为单位,每个扇区为512字节,操作系统读取硬盘时不是一个一扇区读取,而是一次读取多个扇区,多个扇区划分成一个“块”(block),linux以块为单位存储数据,一般块的大小为4KB, 也就是8个扇区组成一个块。
  文件数据都存在块中,那么关于文件信息存储在哪里,比如文件权限访问和修改时间等,我们称为inode,就是专门存放文件的元数据信息,一个分区中如下结构图
如何理解linux的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
如何理解linux的inode

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

如何检查inode

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

  1. 显示文件数据信息
    你可以使用stat显示inode数据在一个文件或目录中, 你需要指定文件或目录的名称
            #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
  2. 显示出文件的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
  3. 显示出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空间但磁盘空间没有满。

  4. 可以使用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.

扫描二维码关注公众号,回复: 6257608 查看本文章
    # 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目录下,如果使用如下方法,产生的软链连将无法使用
[root@centos7 data]# ln -s 1.sh test/test1/1link  
[root@centos7 data]# ll test/test1/1link 
lrwxrwxrwx. 1 root root 4 May 19 17:07 test/test1/1link -> 1.sh  (会有红色闪烁表示不可用)
    正确的方法是:
[root@centos7 data]# ln -s ../../1.sh test/test1/2link
[root@centos7 data]# ll test/test1/2link 
lrwxrwxrwx. 1 root root 10 May 19 17:11 test/test1/2link -> ../../1.sh 
    2. 硬链接
    重要的理解就是inode number, 不是名字,一个硬链接是不同的名称但指向相同的inode number, 所以当你创建一个新的硬链接就相当于给inode增加了一个新的名字而已,

[root@centos7 data]# ls -l 1.sh
-rwx------. 2 root root 0 May 18 15:53 1.sh
[root@centos7 data]# ln 1.sh test/test1/1hard
[root@centos7 data]# ll test/test1/1hard
-rwx------. 2 root root 0 May 18 15:53 test/test1/1hard

    让我们比较一下这两个文件:
[root@centos7 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, 这两个分区文件系统,如果我建立硬链接时会提示如下:
        [root@centos7 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。
    [root@centos7 data]# ll -id /data
    2 drwxr-xr-x. 8 root root 4096 May 19 18:07 /data
    因为在目录创建时本身下会自动创建有一个.和..的代表目录本身和上级目录。
    [root@centos7 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 ..

如何在linux中查找硬链接
    你可以检索所有的文件名指向的inode number, 意思是你可以检索硬链接,因为它是指向相同内容(inode),你可以使用find带有-inum参数
    [root@centos7 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也会建立, 
    [root@centos7 data]# cp test/test1/2link test
    [root@centos7 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
    2. mv文件
    当移动跨文件系统的文件时,也就是跨分区时,mv执行相当于cp命令,只是源文件是被删除的,但是当移动一个文件在同一个文件系统时,文件的inode number不会改变,只有目录下的inode映射会改变,实际的数据在硬盘上并没有移动
    [root@centos7 data]# ls -il samlefile.txt 
    18 -rw-r--r--. 1 root root 0 May 19 17:58 samlefile.txt
    [root@centos7 data]# mv samlefile.txt test  
    [root@centos7 data]# ls -il test/samlefile.txt
    18 -rw-r--r--. 1 root root 0 May 19 17:58 test/samlefile.txt
    3. 删除文件
    当执行rm时,第一步检查文件的链接数,如果链接数大于1,然后只是删除目录下的一条记录,并将链接数减1,数据仍然存在,inode也不受影响。但当链接数为1时,那么inode也会被删除, inode number变为可用,数据块占用的空间将会被划为可用空间块列表。
    [root@centos7 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
    [root@centos7 data]# rm samplefile_hardlink.txt 
    [root@centos7 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.

![](https://s1.51cto.com/images/blog/201905/19/f0af6cdbe45203932be5b25896f3a88a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

猜你喜欢

转载自blog.51cto.com/127601/2397098