一、inode是哪些?

参考文档:

做Android底层驱动或则嵌入式Linux的程序猿常常会遇见一个叫inode的结构体,该结构体特别的重要,而且也比较难懂,所以写一篇理解该inode结构的博客是特别的有必要,屁话不多说,先看inode结构体的定义!

structinode

索引节点对象由inode结构体表示,定义文件在linux/fs.h中。

structinode{

structhlist_nodei_hash;哈希表

structlist_headi_list;索引节点数组

structlist_headi_dentry;目录戒指表

unsignedlongi_ino;节点号

atomic_ti_count;引用记数

umode_ti_mode;访问权限控制

unsignedinti_nlink;硬链接数

uid_ti_uid;使用者id

gid_ti_gid;使用者id组

kdev_ti_rdev;实设备标示符

loff_ti_size;以字节为单位的文件大小

structtimespeci_atime;最后访问时间

structtimespeci_mtime;最后更改(modify)时间

structtimespeci_ctime;最后改变(change)时间

unsignedinti_blkbits;以位为单位的块大小

unsignedlongi_blksize;以字节为单位的块大小

unsignedlongi_version;版本号

unsignedlongi_blocks;文件的块数

unsignedshorti_bytes;使用的字节数

spinlock_ti_lock;载流子锁

structrw_semaphorei_alloc_sem;索引节点讯号量

structinode_operations*i_op;索引节点操作表

structfile_operations*i_fop;默认的索引节点操作

structsuper_block*i_sb;相关的超级块

structfile_lock*i_flock;文件锁链表

structaddress_space*i_mapping;相关的地址映射

structaddress_spacei_data;设备地址映射

structdquot*i_dquot[MAXQUOTAS];节点的c盘限额

structlist_headi_devices;块设备数组

structpipe_inode_info*i_pipe;管线信息

structblock_device*i_bdev;块设备驱动

unsignedlongi_dnotify_mask;目录通知网段

structdnotify_struct*i_dnotify;目录通知

unsignedlongi_state;状态标志

unsignedlongdirtied_when;首次更改时间

unsignedinti_flags;文件系统标志

unsignedchari_sock;套接字

atomic_ti_writecount;写者记数

void*i_security;安全模块

__u32i_generation;索引节点版本号

union{

void*generic_ip;文件特殊信息

}u;

};

理解inode,要从文件存储说起。

文件储存在硬碟上,硬碟的最小储存单位称作"磁道"(Sector)。每位磁道存储512字节(相当于0.5KB)。

操作系统读取硬碟的时侯,不会一个个磁道地读取,这样效率太低,而是一次性连续读取多个磁道,即一次性读取一个"块"(block)。这些由多个磁道组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB查看系统版本linux,即连续八个sector组成一个block。

文件数据都储存在"块"中,这么很其实,我们还必须找到一个地方存储文件的元信息,例如文件的创建者、文件的创建日期、文件的大小等等。这些存储文件元信息的区域就称作inode,英文译名为"索引节点"。

参考文档:@126/blog/static/8/

二、inode的内容

inode包含文件的元信息,具体来说有以下内容:

*文件的字节数

*文件拥有者的UserID

*文件的GroupID

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

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

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

*文件数据block的位置

可以用stat命令,查看某个文件的inode信息:

statexample.txt

其实,不仅文件名以外的所有文件信息,都存在inode之中。至于为何没有文件名,下文会有详尽解释。

三、inode的大小

inode也会消耗硬碟空间linux inode,所以硬碟低格的时侯,操作系统手动将硬碟分成两个区域。一个是数据区,储存文件数据;另一个是inode区(inodetable),储存inode所包含的信息。

每位inode节点的大小,通常是128字节或256字节。inode节点的总量,在低格时就给定,通常是每1KB或每2KB就设置一个inode。假设在一块1GB的硬碟中,每位inode节点的大小为128字节,每1KB就设置一个inode,这么inodetable的大小都会达到128MB,占整块硬碟的12.8%。

查看每位硬碟分区的inode总量和早已使用的数目,可以使用df命令

df-i

查看每位inode节点的大小,可以用如下命令

sudodumpe2fs-h/dev/hda|grep"Inodesize"

因为每位文件都必须有一个inode,因而有可能发生inode早已用光,并且硬碟还未存满的情况。这时linux inode,就难以在硬碟上创建新文件。

四、inode号码

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

这儿值得重复一遍,Unix/Linux系统内部不使用文件名,而使用inode号码来辨识文件。对于系统来说,文件名只是inode号码以便辨识的别名或则外号。表面上,用户通过文件名linux认证,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,按照inode信息,找到文件数据所在的block,读出数据。

使用ls-i命令,可以看见文件名对应的inode号码:

ls-iexample.txt

五、目录文件

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

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

ls命令只列举目录文件中的所有文件名:

ls/etc

ls-i命令列举整个目录文件,即文件名和inode号码:

ls-i/etc

假如要查看文件的详尽信息,就必须依照inode号码,访问inode节点,读取信息。ls-l命令列举文件的详尽信息。

ls-l/etc

六、硬链接

通常情况下,文件名和inode号码是"一一对应"关系,每位inode号码对应一个文件名。并且,Unix/Linux系统容许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行更改,会影响到所有文件名;并且,删掉一个文件名,不影响另一个文件名的访问。这些情况就被称为"硬链接"(hardlink)。

ln命令可以创建硬链接:

ln源文件目标文件

运行里面这条命令之后,源文件与目标文件的inode号码相同,都指向同一个inode。inode信息中有一项称作"链接数",记录指向该inode的文件名总量,这时都会降低1。反过来,删掉一个文件名,才会促使inode节点中的"链接数"减1。当这个值减到0,表明没有文件名指向这个inode,系统还会回收这个inode号码,以及其所对应block区域。

这儿顺便说一下目录文件的"链接数"。创建目录时,默认会生成两个目录项:"."和".."。后者的inode号码就是当前目录的inode号码,等同于当前目录的"硬链接";前者的inode号码就是当前目录的父目录的inode号码,等同于父目录的"硬链接"。所以,任何一个目录的"硬链接"总量,总是等于2加上它的子目录总量(含隐藏目录),这儿的2是父目录对其的“硬链接”和当前目录下的".硬链接“。

七、软链接

不仅硬链接以外,还有一种特殊情况。文件A和文件B的inode号码其实不一样,而且文件A的内容是文件B的路径。读取文件A时,系统会手动将访问者导向文件B。因而,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(softlink)或则"符号链接(symboliclink)。

这意味着,文件A依赖于文件B而存在,假如删掉了文件B,打开文件A都会报错:"Nosuchfileordirectory"。这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因而发生变化。

ln-s命令可以创建软链接。

ln-s源文文件或目录目标文件或目录

八、inode的特殊作用

因为inode号码与文件名分离,这些机制引起了一些Unix/Linux系统特有的现象。

1.有时,文件名包含特殊字符,难以正常删掉。这时,直接删掉inode节点,才能起到删掉文件的作用。

2.联通文件或重命名文件,只是改变文件名,不影响inode号码。

3.打开一个文件之后,系统就以inode号码来辨识这个文件,不再考虑文件名。因而,一般来说,系统未能从inode号码得悉文件名。

第3点促使软件更新显得简单,可以在不关掉软件的情况下进行更新,不须要重启。由于系统通过inode号码,辨识运行中的文件,不通过文件名。更新的时侯,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时侯,文件名就手动指向新版文件,旧版文件的inode则被回收。

九实际问题

在一台配置较低的Linux服务器(显存、硬盘比较小)的/data分区内创建文件时,系统提示c盘空间不足,用df-h命令查看了一下c盘使用情况,发觉/data分区只使用了66%,还有12G的剩余空间,按理说不会出现这些问题。后来用df-i查看了一下/data分区的索引节点(inode),发觉早已用满(IUsed=100%),造成系统未能创建新目录和文件。

查找缘由:

/data/cache目录中存在数目十分多的小字节缓存文件,占用的Block不多,而且占用了大量的inode。

解决方案:

1、删除/data/cache目录中的部份文件,释放出/data分区的一部份inode。

2、用软联接将空闲分区/opt中的newcache目录联接到/data/cache,使用/opt分区的inode来减轻/data分区inode不足的问题:

ln-s/opt/newcache/data/cache

本文原创地址:https://www.linuxprobe.com/txwijgtbkfx.html编辑:刘遄,审核员:暂无