VFS四大对象之二 struct inode

继上一篇文章:https://cloud.tencent.com/developer/article/1053842

二、inode结构体:(转自http://blog.csdn.net/shanshanpt/article/details/38943731

inode结构体在(include/linux/fs.h中):

保存的其实是实际的数据的一些信息,这些信息称为“元数据”(也就是对文件属性的描述)。例如:文件大小,设备标识符,用户标识符,用户组标识符,文件模式,扩展属性,文件读取或修改的时间戳,链接数量,指向存储该内容的磁盘区块的指针,文件分类等等。

( 注意数据分成:元数据+数据本身 )

同时注意:inode有两种,一种是VFS的inode,一种是具体文件系统的inode。前者在内存中,后者在磁盘中。所以每次其实是将磁盘中的inode调进填充内存中的inode,这样才是算使用了磁盘文件inode。

注意inode怎样生成的:每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定(现代OS可以动态变化),一般每2KB就设置一个inode。一般文件系统中很少有文件小于2KB的,所以预定按照2KB分,一般inode是用不完的。所以inode在文件系统安装的时候会有一个默认数量,后期会根据实际的需要发生变化。

注意inode号:inode号是唯一的,表示不同的文件。其实在Linux内部的时候,访问文件都是通过inode号来进行的,所谓文件名仅仅是给用户容易使用的。当我们打开一个文件的时候,首先,系统找到这个文件名对应的inode号;然后,通过inode号,得到inode信息,最后,由inode找到文件数据所在的block,现在可以处理文件数据了。

inode和文件的关系:当创建一个文件的时候,就给文件分配了一个inode。一个inode只对应一个实际文件,一个文件也会只有一个inode。inodes最大数量就是文件的最大数量。

 1 struct inode {
 2     umode_t            i_mode;
 3     unsigned short        i_opflags;
 4     uid_t            i_uid;
 5     gid_t            i_gid;
 6     unsigned int        i_flags;
 7 
 8 #ifdef CONFIG_FS_POSIX_ACL
 9     struct posix_acl    *i_acl;
10     struct posix_acl    *i_default_acl;
11 #endif
12 
13     const struct inode_operations    *i_op;
14     struct super_block    *i_sb;
15     struct address_space    *i_mapping;
16 
17 #ifdef CONFIG_SECURITY
18     void            *i_security;
19 #endif
20 
21     /* Stat data, not accessed from path walking */
22     unsigned long        i_ino;
23     /*
24      * Filesystems may only read i_nlink directly.  They shall use the
25      * following functions for modification:
26      *
27      *    (set|clear|inc|drop)_nlink
28      *    inode_(inc|dec)_link_count
29      */
30     union {
31         const unsigned int i_nlink;
32         unsigned int __i_nlink;
33     };
34     dev_t            i_rdev;
35     struct timespec        i_atime;
36     struct timespec        i_mtime;
37     struct timespec        i_ctime;
38     spinlock_t        i_lock;    /* i_blocks, i_bytes, maybe i_size */
39     unsigned short          i_bytes;
40     blkcnt_t        i_blocks;
41     loff_t            i_size;
42 
43 #ifdef __NEED_I_SIZE_ORDERED
44     seqcount_t        i_size_seqcount;
45 #endif
46 
47     /* Misc */
48     unsigned long        i_state;
49     struct mutex        i_mutex;
50 
51     unsigned long        dirtied_when;    /* jiffies of first dirtying */
52 
53     struct hlist_node    i_hash;
54     struct list_head    i_wb_list;    /* backing dev IO list */
55     struct list_head    i_lru;        /* inode LRU list */
56     struct list_head    i_sb_list;
57     union {
58         struct list_head    i_dentry;
59         struct rcu_head        i_rcu;
60     };
61     atomic_t        i_count;
62     unsigned int        i_blkbits;
63     u64            i_version;
64     atomic_t        i_dio_count;
65     atomic_t        i_writecount;
66     const struct file_operations    *i_fop;    /* former ->i_op->default_file_ops */
67     struct file_lock    *i_flock;
68     struct address_space    i_data;
69 #ifdef CONFIG_QUOTA
70     struct dquot        *i_dquot[MAXQUOTAS];
71 #endif
72     struct list_head    i_devices;
73     union {
74         struct pipe_inode_info    *i_pipe;
75         struct block_device    *i_bdev;
76         struct cdev        *i_cdev;
77     };
78 
79     __u32            i_generation;
80 
81 #ifdef CONFIG_FSNOTIFY
82     __u32            i_fsnotify_mask; /* all events this inode cares about */
83     struct hlist_head    i_fsnotify_marks;
84 #endif
85 
86 #ifdef CONFIG_IMA
87     atomic_t        i_readcount; /* struct files open RO */
88 #endif
89     void            *i_private; /* fs or device private pointer */
90 };

i_hash:指向hash链表指针,用于inode的hash表,下面会说

i_list:指向索引节点链表指针,用于inode之间的连接,下面会说

i_dentry:指向目录项链表指针,注意一个inodes可以对应多个dentry,因为一个实际的文件可能被链接到其他的文件,那么就会有另一个dentry,这个链表就是将所有的与本inode有关的dentry都连在一起。

i_dirty_buffersi_dirty_data_buffers:脏数据缓冲区

i_ino:索引节点号,每个inode都是唯一的

i_count:引用计数

i_dev:如果inode代表设备,那么就是设备号

i_mode:文件的类型和访问权限

i_nlink:与该节点建立链接的文件数(硬链接数)

i_uid:文件拥有者标号

i_gid:文件所在组标号

i_rdev:实际的设备标识

注意i_dev和i_rdev之间区别:如果是普通的文件,例如磁盘文件,存储在某块磁盘上,那么i_dev代表的就是保存这个文件的磁盘号,但是如果此处是特殊文件例如就是磁盘本身(因为所有的设备也看做文件处理),那么i_rdev就代表这个磁盘实际的磁盘号。

i_size:inode所代表的的文件的大小,以字节为单位

i_atime:文件最后一次访问时间

i_mtime:文件最后一次修改时间

i_ctime:inode最后一次修改时间

i_blkbits:块大小,字节单位

i_blksize:块大小,bit单位

i_blocks:文件所占块数

i_version:版本号

i_bytes:文件中最后一个块的字节数

i_sem:指向用于同步操作的信号量结构

i_alloc_sem:保护inode上的IO操作不被另一个打断

i_zombie:僵尸inode信号量

i_op:索引节点操作

i_fop:文件操作

i_sb:inode所属文件系统的超级块指针

i_wait:指向索引节点等待队列指针

i_flock:文件锁链表

注意下面:address_space不是代表某个地址空间,而是用于描述页高速缓存中的页面的。一个文件对应一个address_space,一个address_space和一个偏移量可以确定一个页高速缓存中的页面。

i_mapping:表示向谁请求页面

i_data:表示被inode读写的页面

i_dquot:inode的磁盘限额

关于磁盘限额:在多任务环境下,对于每个用户的磁盘使用限制是必须的,起到一个公平性作用。

磁盘限额分为两种:block限额和inode限额,而且对于一个特文件系统来说,使用的限额机制都是一样的,所以限额的操作函数

放在super_block中就OK!

i_devices:设备链表。共用同一个驱动程序的设备形成的链表。

i_pipe:指向管道文件(如果文件是管道文件时使用)

i_bdev:指向块设备文件指针(如果文件是块设备文件时使用)

i_cdev:指向字符设备文件指针(如果文件是字符设备时使用)

i_dnotify_mask:目录通知事件掩码

i_dnotify:用于目录通知

i_state:索引节点的状态标识:I_NEW,I_LOCK,I_FREEING

i_flags:索引节点的安装标识

i_sock:如果是套接字文件则为True

i_write_count:记录多少进程以刻写模式打开此文件

i_attr_flags:文件创建标识

i_generation:保留

u:具体的inode信息

注意管理inode的四个链表

inode_unused:将目前还没有使用的inode链接起来(通过i_list域链接)

inode_in_use:目前正在使用的inode链接起来(通过i_list域链接)

super_block中的s_dirty:将所有修改过的inode链接起来,这个字段在super_block中(通过i_list域链接起来)

inode_hashtable:注意为了加快inode的查找效率,将正在使用的inode和脏inode也会放在inode_hashtable这样一个hash结构中,

但是,不同的inode的hash值可能相等,所以将hash值相等的这些inode通过这个i_hash字段连接起来。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JAVA同学会

JAVA9模块化详解(二)——模块的使用

各自的模块可以在模块工件中定义,要么就是在编译期或者运行期嵌入的环境中。为了提供可靠的配置和强健的封装性,在分块的模块系统中利用他们,必须确定它们的位置,然后决...

492
来自专栏数据库

JDBC常见错误及解决方案

最近很多同学在数据库编程这一块遇到了很多的问题,各种问题都有,但却苦于不知道怎么解决这些问题,以至于编程效率非常低。今天我就来总结一下在数据库编程时经常遇到的问...

1948
来自专栏码匠的流水账

java9迁移注意事项

1、代码不模块化,先迁移到jdk9上,好利用jdk9的api 2、代码同时也模块化迁移

461
来自专栏java 成神之路

jvm 性能调优工具之 jmap

36012
来自专栏linux驱动个人学习

解析Linux中的VFS文件系统之文件系统的注册(二)

继上一篇文章:https://cloud.tencent.com/developer/article/1053882 3. 文件系统的注册 这里的文件系统是指可...

3226
来自专栏企鹅号快讯

用户空间和内核空间

学习 Linux 时,经常可以看到两个词:User space(用户空间)和Kernel space(内核空间)。 简单说,Kernel space 是 Lin...

1858
来自专栏我的博客

Strace命令手册

strace简介 strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘...

3468
来自专栏magicsoar

初识nginx——配置解析篇

一、nginx的介绍     nginx是由俄罗斯人开发的一款高性能的http和反向代理服务器,也可以用来作为邮件代理。相比较于其他的服务器,具有占用内存少,稳...

2078
来自专栏北京马哥教育

LVM详解

petmaster出品 必是精品 一、概述 LVM全称为Logical Volume Manager,即逻辑卷管理器。LVM可以弹性的调整文件系统的容...

2469
来自专栏企鹅号快讯

NPM酷库:vm2,安全的沙箱环境

NPM酷库,每天两分钟,了解一个流行NPM库。 今天我们要了解的库是 vm2,这是一个Node.js 官方 vm 库的替代品,主要解决了安全问题。 不安全的vm...

2115

扫描关注云+社区