linux 文件系统inode

linux 文件系统inode

  1. 简介

    1
    2
    3
    4
    inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础

    理解inode,不仅有助于提高系统操作水平,还有助于体会Unix设计哲学,即:
    如何把底层的复杂性抽象成一个简单概念,从而大大简化用户接口
  2. inode是什么?

    1
    2
    3
    4
    5
    理解inode,
    首先,需要从文件存储说起,文件存储在硬盘上
    其次,硬盘的最小存储单位叫做"扇区"(Sector),每个扇区存储512字节(相当于0.5KB).
    然后,操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block).这种由多个扇区组成的"块",是文件存取的最小单位."块"的大小,最常见的是4KB,即连续八个"扇区"组成一个"块".
    最后,文件的数据都储存在"块"中,我们还必须找到一个地方储存文件的元信息(比如,文件的创建者,文件的创建日期,文件的大小等等).这种储存文件元信息的区域就叫做inode,中文译名为"索引节点".每一个文件都有对应的inode,里面包含了与该文件有关的一些信息
  3. inode的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    inode包含的元信息:
    * 文件的字节数
    * 文件属主
    * 文件数组
    * 文件的读,写,执行权限
    * 文件数据块的位置
    * 链接数,即有多少文件名指向这个inode
    * 文件的时间戳:
    ctime指inode上一次变动的时间
    mtime指文件内容上一次变动的时间
    atime指文件上一次打开的时间

    [root@dev ~]# touch smallasa.txt
    [root@dev ~]# stat smallasa.txt
    File: ‘smallasa.txt’
    Size: 0 Blocks: 0 IO Block: 4096 regular empty file
    Device: fd01h/64769d Inode: 67237570 Links: 1
    Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
    Access: 2017-09-15 10:28:57.304438000 +0800
    Modify: 2017-09-15 10:28:57.304438000 +0800
    Change: 2017-09-15 10:28:57.304438000 +0800
    Birth: -
  4. inode的大小

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域:
    一个是数据区,用于存放文件数据
    一个是inode区(inode table),用于存放inode所包含的信息

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

    //查看磁盘inode总数,使用量
    [root@dev ~]# df -i
    Filesystem Inodes IUsed IFree IUse% Mounted on
    /dev/mapper/centos-root 18358272 113044 18245228 1% /
    devtmpfs 483828 358 483470 1% /dev
    tmpfs 485436 1 485435 1% /dev/shm
    tmpfs 485436 424 485012 1% /run
    tmpfs 485436 13 485423 1% /sys/fs/cgroup
    /dev/vdb 104857600 55773 104801827 1% /mnt
    /dev/vda1 512000 330 511670 1% /boot
    tmpfs 485436 1 485435 1% /run/user/0
  5. inode号码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    每个inode都有一个号码,操作系统用inode号码来识别不同的文件

    注意: Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件.对于系统来说,文件名只是inode号码便于识别的别称或者绰号

    用户打开文件,实际上系统内部经过了三个步骤:
    首先,系统找到这个文件名对应的inode号码
    其次,通过inode号码,获取inode信息
    最后,根据inode信息,找到文件数据所在的block,读出数据

    //查看文件inode号
    [root@dev ~]# ls -i smallasa.txt
    67237570 smallasa.txt
  6. 目录文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Unix/Linux系统中,目录(directory)也是一种文件.打开目录,实际上就是打开目录文件
    目录文件的结构非常简单,就是一系列目录项(dirent)的列表.每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码


    [root@dev ~]# mkdir test
    [root@dev ~]# touch test/{a,b,c}
    [root@dev ~]# ls -i test/
    154095 a 154103 b 154104 c
    [root@dev ~]# ls -l test/
    total 0
    -rw-r--r-- 1 root root 0 Sep 15 10:55 a
    -rw-r--r-- 1 root root 0 Sep 15 10:55 b
    -rw-r--r-- 1 root root 0 Sep 15 10:55 c
  7. 硬链接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名
    但是,Unix/Linux系统允许多个文件名指向同一个inode号码,这意味着可以用不同的文件名访问同样的内容,对文件内容进行修改,会影响到所有文件名,但是,删除一个文件名,不影响另一个文件名的访问.这种情况就被称为"硬链接"(hard link)


    [root@dev ~]# ls -li smallasa.txt
    67237570 -rw-r--r-- 1 root root 0 Sep 15 10:59 smallasa.txt
    [root@dev ~]# ln smallasa.txt smallasa.A
    [root@dev ~]# ls -li smallasa.txt smallasa.A
    67237570 -rw-r--r-- 2 root root 0 Sep 15 10:59 smallasa.A
    67237570 -rw-r--r-- 2 root root 0 Sep 15 10:59 smallasa.txt

    如上:
    inode信息中有一项叫做"链接数",记录指向该inode的文件名总数.
    每创建一个硬链接,会使得inode节点中的"链接数"加1
    每删除一个硬链接,会使得inode节点中的"链接数"减1
    inode节点中的"链接数"减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域

    [root@dev ~]# mkdir test
    [root@dev ~]# ls -lia test/
    total 4
    68058947 drwxr-xr-x 2 root root 6 Sep 15 11:08 .
    67149953 dr-xr-x---. 17 root root 4096 Sep 15 11:08 ..
    [root@dev ~]# ls -liad test/
    68058947 drwxr-xr-x 2 root root 6 Sep 15 11:08 test/

    如上,
    创建目录时,默认会生成两个目录项: "." 和 ".."
    前者的inode号码就是当前目录的inode号码,等同于当前目录的"硬链接"
    后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的"硬链接"
    所以,任何一个目录的"硬链接"总数,总是等于2
  8. 软连接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径.当读取文件A时,系统会自动将访问者导向文件B.因此,无论打开哪一个文件,最终读取的都是文件B.这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接"(symbolic link)

    这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错: "No such file or directory".这是软链接与硬链接最大的不同: 文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化

    [root@dev ~]# ls -li smallasa.txt
    67237570 -rw-r--r-- 1 root root 0 Sep 15 10:59 smallasa.txt
    [root@dev ~]# ln -s smallasa.txt smallasa.A
    [root@dev ~]# ls -li smallasa.txt smallasa.A
    68058948 lrwxrwxrwx 1 root root 12 Sep 15 11:14 smallasa.A -> smallasa.txt
    67237570 -rw-r--r-- 1 root root 0 Sep 15 10:59 smallasa.txt
  9. inode的特殊作用

    1
    2
    3
    4
    5
    6
    由于inode号码与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象:
    1.有时文件名包含特殊字符,无法正常删除.这时,直接删除inode节点,就能起到删除文件的作用
    2.移动文件或重命名文件时,只是改变文件名,不影响inode号码
    3.打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名.因此,系统无法从inode号码得知文件名

    第3点使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启.因为系统通过inode号码,识别运行中的文件,不通过文件名.更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件.等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收.