一. 背景

   在一台Linux主机中,某分区提示磁盘空间已经耗尽,使用两个命令查看:

     df -h /AA   (AA为分区)    --》 查看磁盘使用情况

     df -i  /AA             --》 查看分区inode 使用情况

wKioL1ea32yBe2TwAAAINbmPvqg122.gif-wh_50



如图示: 磁盘空间实际才使用66% , 但是Inode 数量已经使用 100%。

二. 磁盘工作原理以及 inode 概念

   硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性读取一个"块"(block),每个"块"(block)由八个连续的sector组成。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,文件数据都储存在"块"中,那么还必须找到一个地方储存文件的元信息(磁盘中数据的索引),比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

   inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。

   假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

三. inode 的结构、内容

   inode( index node)表中包含文件系统所有文件列表

每个inode都有一个号码,操作系统用inode号码来识别不同的文件。

一个节点 (索引节点)是在一个表项,包含有关文件的信息

  具体有以下内容:

      * 文件的字节数

      * 文件拥有者的User ID

      * 文件的Group ID

      * 文件的读、写、执行权限

      * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次

    变动的时间,atime指文件上一次打开的时间。

      * 链接数,即有多少文件名指向这个inode

      * 文件数据block的位置(由此信息才能最终读取到数据)

注:每个inode都有一个号码,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件

对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。


   使用命令 stat 可以查看inode 信息

    [root@CentOS68NO1]# stat abc/

      File: `abc/'

      Size: 4096       Blocks: 8          IO Block: 4096   directory

    Device: 803h/2051d Inode: 130647      Links: 4

    Access: (0700/drwx------)  Uid: (  500/  abc)   Gid: (  500/  abc)

    Access: 2014-08-12 10:46:02.810999643 +0800

    Modify: 2014-07-23 07:19:01.146989703 +0800

    Change: 2014-07-23 07:19:01.146989703 +0800

     inode 结构示意图

wKiom1ea33PgiqK_AAHsbLw3xaI430.png-wh_50

如上图所示,系统内部这个过程分成三步:

    首先,系统找到这个文件名对应的inode号码(读取磁盘中对应的inode区);

    其次,通过inode号码,获取inode信息(读取图中最左边的列表);

    最后,根据inode信息,找到文件数据所在的block,读出数据。

(根据inode中数据块位置的指针,找到对应的数据块,读取数据)

(由上图可知,指针可以有多级,因文件系统的不同,块大小会不同,当一个文件过大时,一个块中空间不足以存放该文件的指针,就需要拓展下一级块来存放指针,以此类推)


四. 硬链接、目录与inode

  目录与inode

Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。

目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。

wKioL1ea33DT7TzdAAEqgVrS4aA996.png-wh_50

硬链接

一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,允许多个文件名指向同一个inode号码。

这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问(相当于一个文件的别名)。这种情况就被称为"硬链接"(hard link)。    


  特点:

    创建硬链接会增加额外的记录项以引用文件

    对应于同一文件系统上一个物理文件

    每个目录引用相同的inode号

    创建时链接数递增

    删除文件时:

    rm命令递减计数的链接

    文件要存在,至少有一个链接数

    当链接数为零时,该文件被删除

    不能跨越驱动器或分区

    语法:

    ln filename [linkname ]

软链接:

  文件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"链接数"不会因此发生变化。

软链接:相当于快捷方式,可以跨分区,不改变硬链接数、inode号,不可以指向自身


    一个符号链接指向另一个文件

    ls - l的 显示链接的名称和引用的文件

    一个符号链接的内容是它引用文件的名称

    可以对目录进行

    可以跨分区

    指向的是另一个文件的路径;其大小为指向的路径字符串的

    长度;不增加或减少目标文件inode的引用计数;

    语法:

    ln -s filename [linkname]

五. inode 与部分命令操作关系

  CP命令下:

分配一个空闲的inode号,在inode表中生成新条目在目录中创建一个目录项,将名称与inode编号关联拷贝数据生成新的文件

   rm 命令下:

链接数递减,从而释放的inode号可以被重用把数据块放在空闲列表中删除目录项

数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖。

   mv命令下 :

如果mv命令的目标和源在相同的文件系统,作为mv 命令

用新的文件名创建对应新的目录项,删除旧目录条目对应的旧的文件名

不影响inode表(除时间戳)或磁盘上的数据位置(没有数据被移动!)

如果目标和源在一个不同的文件系统, mv相当于cp和rm