一、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
本文原创地址://lrxjmw.cn/txwijgtbkfx.html编辑:刘遄,审核员:暂无