Linux文件编程之虚拟文件系统(VFS)(8)

i_list :所有索引结点形成的双联表,(从图上可以看出,索引节点对象是靠它来链接的)
i_dentry :所有引用该inode的目录项将形成一个双联表,该字段即为这个双联表的头结点
i_ino :索引结点号。通过ls -i命令可以查看文件的索引节点号;
i_count :引用计数;
i_nlink :硬链接数。当该inode描述一个目录时,这个值至少为2,代表.和..的数目;
i_uid :inode所属文件的拥有者的id,通过ls -n可查看拥有者id;
i_gid :inode所属文件所在组的id,通过ls -n可查看组id;
i_rdev :如果该inode描述的是一个设备文件,此值为设备号;
i_blkbits :以位为单位的块大小;
i_atime :文件最近一次被访问的时间。通过ls -lu可查看该时间;
i_mtime :文件最近一次被修改的时间,这里的修改只文件内容被修改。通过ls -l可查看该时间;
i_ctime :文件最近一次被修改的时间,这里的修改除了指文件内容被修改外,更强调的是文件的属性被修改。通过ls -lc可查看该时间;
i_blocks :文件使用块的个数,通过ls -s可以查看该某个文件的块使用数目;
i_mode :文件的访问权限;
i_op :    指向索引结点操作结构体的指针;
i_fop :  指向文件操作街头体的指针;
i_sb :    指向inode所属文件系统的超级块的指针;
i_pipe :如果inode所代表的文件是一个管道,则使用该字段;
i_bdev :如果inode所代表的文件是一个块设备,则使用该字段;
i_cdev :如果inode所代表的文件是一个字符设备,则使用该字段;

i_state  :  索引节点的状态信息。

Tiger-John说明:

1.在同一个文件系统中,每个索引节点号都是唯一的,内核可以根据索引节点号的散列值来查找其inode结构。

2.inode中有两个设备号i_dev和i_rdev。

a.特设文件外,每个节点都存储在某个设备上,这就是i_dev。

b. 如果索引节点所代表的并不是常规文件,而是某个设备,则需要另一个设备号,这就是i_rdev。

3.对i_state的说明:

每个VFS索引节点都会复制磁盘索引节点包含的一些数据,比如文件占有的磁盘数。如果i_state 的值等于I_DIR,该索引节点就是“脏“的。也就是说,对应的磁盘索引节点必须被更新。

4.三个重要的双向链表:

a.未用索引节点链表,正在使用索引节点链表和脏索引节点链表。每个索引节点对象总是出现在上面三种的一个。

b.这3个链表都是通过索引节点的i_list 域链接在一起的。

c.属于“正在使用“或“脏“链表的索引节点对象也同时存放在一个散列表中。

<散列表加快了对索引节点对象的搜索>.

5.一个索引节点代表文件系统中的一个文件,它也可 以是设备或管道这样的特殊文件。所以在索引节点结构体中有一些和特殊文件相关的项。
6.有时候某些文件系统并不能完整地包含索引节点结构体要求的所有信息。那么此时刚怎么办呢?

此时,可以给它赋一些其它的值。

例如:一个文件系统可能并不记录文件的访问时间,这时就可以在i_atime中存储0。

7.i_list和i_sb_list的区别

a:i_list:VFS中使用四个链表来管理不同状态的inode结点。inode_unused将当前未使用的inode链接起来,inode_in_use将当前正在被使用的inode链接起来,超级块中的s_dirty将所有脏inode链接起来,i_hash将所有hash值相同的inode链接起来。i_list中包含prev和next两个指针,分别指向与当前inode处于同一个状态链表的前后两个元素

b.i_sb_list:每个文件系统中的inode都会形成一个双联表,这个双链表的头结点存放在超级块的s_inodes中。而该字段中的prev和next指针分别指向在双链表中与其相邻的前后两个元素

c..索引结点中i_sb_list链表是链接一个文件系统中所有inode的链表,因此相邻的inode之间均会由此链表链接;而i_list链接的是处于同一个状态的所有inode。所以,相邻inode之间并不一定链接在一起。

4>与索引节点关联的方法叫索引节点操作表,它是在 struct inode_operations这个结构体中具体描述的。它的定义在 include/linux/fs.h头文件中定义。


1516struct inode_operations {
1517        int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
1518        struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
1519        int (*link) (struct dentry *,struct inode *,struct dentry *);
1520        int (*unlink) (struct inode *,struct dentry *);
1521        int (*symlink) (struct inode *,struct dentry *,const char *);
1522        int (*mkdir) (struct inode *,struct dentry *,int);
1523        int (*rmdir) (struct inode *,struct dentry *);
1524        int (*mknod) (struct inode *,struct dentry *,int,dev_t);
1525        int (*rename) (struct inode *, struct dentry *,
1526                        struct inode *, struct dentry *);
1527        int (*readlink) (struct dentry *, char __user *,int);
1528        void * (*follow_link) (struct dentry *, struct nameidata *);
1529        void (*put_link) (struct dentry *, struct nameidata *, void *);
1530        void (*truncate) (struct inode *);
1531        int (*permission) (struct inode *, int);
1532        int (*check_acl)(struct inode *, int);
1533        int (*setattr) (struct dentry *, struct iattr *);
1534        int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
1535        int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
1536        ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
1537        ssize_t (*listxattr) (struct dentry *, char *, size_t);
1538        int (*removexattr) (struct dentry *, const char *);
1539        void (*truncate_range)(struct inode *, loff_t, loff_t);
1540        long (*fallocate)(struct inode *inode, int mode, loff_t offset,
1541                          loff_t len);
1542        int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
1543                      u64 len);
1544};

inode_operations对象包括了内核针对特定文件所能调用的方法。

现在我们对其中一些重要的结果进行分析:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwszjs.html