inode结构体成员详解
概述:inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间、档名、使用者及群组等。inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inode。在阅读文件系统源码的时候,必须对这个结构有着清醒的认识。下面分别对VFS inodee与Ext2 inode做一下简单的描述:
1.VFS inode
VFS inode包含文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等信息。它是linux管理文件系统的最基本单位,也是文件系统连接任何子目录、文件的桥梁。inode结构中的静态信息取自物理设备上的文件系统,由文件系统指定的函数填写,它只存在于内存中,可以通过inode缓存访问。虽然每个文件都有相应的inode结点,但是只有在需要的时候系统才会在内存中为其建立相应的inode数据结构,建立的inode结构将形成一个链表,我们可以通过遍历这个链表去得到我们需要的文件结点,VFS也为已分配的inode构造缓存和哈希表,以提 高系统性能。inode结构中的struct inode_operations *i_op为我们提供了一个inode操作列表,通过这个列表提供的函数我们可以对VFS inode结点进行各种操作。每个inode结构都有一个i结点号i_ino,在同一个文件系统中每个i结点号是唯一的。
struct inode {
struct list_headi_hash;
struct list_headi_list;
struct list_headi_dentry;
struct list_headi_dirty_buffers;
unsigned longi_ino; /*每一个inode都有一个序号,经由super block结构和其序号,我们可以很轻易的找到这个inode。*/
atomic_t i_count; /*在Kernel里,很多的结构都会记录其reference count,以确保如果某个结构正在使用,它不会被不小心释放掉,i_count就是其reference count。*/
kdev_t i_dev; /* inode所在的device代码 */
umode_t i_mode; /* inode的权限 */
nlink_t i_nlink; /* hard link的个数 */
uid_t i_uid; /* inode拥有者的id */
gid_t i_gid; /* inode所属的群组id */
kdev_t i_rdev; /* 如果inode代表的是device的话,那此字段将记录device的代码 */
off_t i_size; /* inode所代表的档案大小 */
time_t i_atime; /* inode最近一次的存取时间 */
time_t i_mtime; /* inode最近一次的修改时间 */
time_t i_ctime; /* inode的产生时间 */
unsigned long i_blksize; /* inode在做IO时的区块大小 */
unsigned long i_blocks; /* inode所使用的block数,一个block为512 byte*/
unsigned long i_version; /* 版本号码 */
unsigned short i_bytes;
struct semaphore i_sem;
struct rw_semaphore i_truncate_sem;
struct semaphore i_zombie;
struct inode_operations *i_op;
struct file_operations *i_fop;/* former ->i_op->default_file_ops */
struct super_block *i_sb; /* inode所属档案系统的super block */
wait_queue_head_t i_wait;
struct file_lock *i_flock; /* 用来做file lock */
struct address_space *i_mapping;
struct address_space i_data;
struct dquot *i_dquot [MAXQUOTAS];
/* These three should probably be a union */
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct char_device *i_cdev;
unsigned longi_dnotify_mask; /* Directory notify events */
struct dnotify_struct *i_dnotify; /* for directory notifications */
unsigned long i_state; /* inode目前的状态,可以是I_DIRTY,I_LOCK和 I_FREEING的OR组合 */
unsigned int i_flags; /* 记录此inode的参数 */
unsigned char i_sock; /* 用来记录此inode是否为socket */
atomic_t i_write count;
unsigned int i_attr_flags; /* 用来记录此inode的属性参数 */
__u32 i_generation;
union {
struct minix_inode_info minix_i;
struct ext2_inode_info ext2_i;
struct ext3_inode_info ext3_i;
struct hpfs_inode_info hpfs_i;
struct ntfs_inode_info ntfs_i;
struct msdos_inode_info msdos_i;
struct umsdos_inode_info umsdos_i;
struct iso_inode_info isofs_i;
struct sysv_inode_info sysv_i;
struct affs_inode_info affs_i;
struct ufs_inode_info ufs_i;
struct efs_inode_info efs_i;
struct romfs_inode_info romfs_i;
struct shmem_inode_info shmem_i;
struct coda_inode_info coda_i;
struct smb_inode_info smbfs_i;
struct hfs_inode_info hfs_i;
struct adfs_inode_info adfs_i;
struct qnx4_inode_info qnx4_i;
struct reiserfs_inode_info reiserfs_i;
struct bfs_inode_info bfs_i;
struct udf_inode_info udf_i;
struct ncp_inode_info ncpfs_i;
struct proc_inode_info proc_i;
struct socketsocket_i;
struct usbdev_inode_info usbdev_i;
struct jffs2_inode_infojffs2_i;
void *generic_ip;
} u;
};
1) i_state:如果这个字段等于I_DIRTY_SYNC ,I_DIRTY_DATASYNC, I_DIRTY_PAGES,这个索引节点是脏的,就是说对应磁盘索引节点必须更新(磁盘和内存数据已经不一致了)。
2)每个索引节点,总是出现在三个双向循环链表的某一个之中(inode_unused,inode_in_use,s_dirty),这三个链表的意义:
· 正在使用的索引节点链表。全局变量inode_in_use指向该链表中的首元素和尾元素。函数get_empty_inode()获得一个空节点,get_new_inode()获得一个新节点,通过这两个函数新分配的索引节点就加入到这个链表中。
· 未用索引节点链表。全局变量inode_unused的next域 和prev域分别指向该链表中的首元素和尾元素。
· 脏索引节点链表。由相应超级块的s_dirty域指向该链表中的首元素和尾元素。
3)全局哈希表inode_hashtable,其中哈希值是根据每个超级块指针的值和32位索引节点号而得。对没有超级块的索引节点(inode->i_sb == NULL),则将其加入到anon_hash_chain链表的首部。例如,net/socket.c中sock_alloc()函数, 通过调用fs/inode.c中get_empty_inode()创建的套接字是一个匿名索引节点,这个节点就加入到了anon_hash_chain链表。这个hash表用于保存inode对象,为了解决冲突问题,ionde有i_hash字段,该字段包含两个指针,用于解决映射到同一个地址的inode节点的链接问题。
4)索引节点操作inode_operations:
792 struct inode_operations {
793 int (*create) (struct inode *,struct dentry *,int);
794 struct dentry * (*lookup) (struct inode *,struct dentry *);
795 int (*link) (struct dentry *,struct inode *,struct dentry *);
796 int (*unlink) (struct inode *,struct dentry *);
797 int (*symlink) (struct inode *,struct dentry *,const char *);
798 int (*mkdir) (struct inode *,struct dentry *,int);
799 int (*rmdir) (struct inode *,struct dentry *);
800 int (*mknod) (struct inode *,struct dentry *,int,int);
801 int (*rename) (struct inode *, struct dentry *,
802 struct inode *, struct dentry *);
803 int (*readlink) (struct dentry *, char *,int);
804 int (*follow_link) (struct dentry *, struct nameidata *);
805 void (*truncate) (struct inode *);
806 int (*permission) (struct inode *, int);
807 int (*revalidate) (struct dentry *);
808 int (*setattr) (struct dentry *, struct iattr *);
809 int (*getattr) (struct dentry *, struct iattr *);
810 };
2、EXT2 inode
用来定义文件系统的结构以及描述系统中每个文件的管理信息,每个文件都有且只有一个inode,即使文件中没有数据,其索引结点也是存在的。每个文件用一个单独的Ext2 inode结构来描述,而且每一个inode都有唯一的标志号。Ext2 inode为内存中的inode结构提供了文件的基本信息,随着内存中inode结构的变化,系统也将更新Ext2 inode中相应的内容。Ext2 inode对应的是Ext2_inode结构。
struct ext2_inode {
__u16 i_mode;/* File mode */
__u16 i_uid;/* Low 16 bits of Owner Uid */
__u32 i_size;/* Size in bytes */
__u32 i_atime;/* Access time */
__u32 i_ctime;/* Creation time */
__u32 i_mtime;/* Modification time */
__u32 i_dtime;/* Deletion Time */
__u16 i_gid;/* Low 16 bits of Group Id */
__u16 i_links_count;/* Links count */
__u32 i_blocks;/* Blocks count */
__u32 i_flags;/* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1;/* OS dependent 1 */
__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32 i_generation;/* File version (for NFS) */
__u32 i_file_acl;/* File ACL */
__u32 i_dir_acl;/* Directory ACL */
__u32 i_faddr;/* Fragment address */
union {
struct {
__u8l_ i_frag;/* Fragment number */
__u8l_ i_fsize;/* Fragment size */
__u16 i_pad1;
__u16l_ i_uid_high;/* these 2 fields */
__u16l_ i_gid_high;/* were reserved2[0] */
__u32l_ i_reserved2;
} linux2;
struct {
__u8h_ i_frag;/* Fragment number */
__u8h_ i_fsize;/* Fragment size */
__u16h_ i_mode_high;
__u16h_ i_uid_high;
__u16h_ i_gid_high;
__u32h_ i_author;
} hurd2;
struct {
__u8m_ i_frag;/* Fragment number */
__u8m_ i_fsize;/* Fragment size */
__u16m_ pad1;
__u32m_ i_reserved2[2];
} masix2;
} osd2;/* OS dependent 2 */
};
从结构的定义中可以看出来inode(VFS inode)与ext2_inode的差别是很大的,它们都包含动态信息和静态信息,通过union指定的内容一定是动态的。inode结构中的union u实际上反映了VFS支持的文件系统。
可以看出inode结构与ext2_inode结构有些内容是相似的,如:
inode定义的
unsigned long i_ino;
umode_t i_mode;
nlink_t i_nlink;
uid_t i_uid;
gid_t i_gid;
loff_t i_size;
time_t i_atime;
time_t i_mtime;
time_t i_ctime;
unsigned long i_blksize;
unsigned long i_blocks;
和ext2_inode定义的定义部分
__u16 i_mode;/* File mode */
__u16 i_uid;/* Low 16 bits of Owner Uid */
__u32 i_size;/* Size in bytes */
__u32 i_atime;/* Access time */
__u32 i_ctime;/* Creation time */
__u32 i_mtime;/* Modification time */
__u32 i_dtime;/* Deletion Time */
__u16 i_gid;/* Low 16 bits of Group Id */
__u16 i_links_count;/* Links count */
__u32 i_blocks;/* Blocks count */
__u32 i_flags;/* File flags */
这些都可以对应上,当然还有一些不同的地方,如inode中定义的
kdev_t i_rdev;
kdev_t i_dev;
unsigned short i_bytes;
struct semaphore i_sem;
在ext2_inode中没有体现,不过这部分对ext2_inode是没有用途而且无法确定的。类似的,可以推广到两个结构的其余部分,最终在代码中的区别还是与原理中分析的区别相关的,也是原理的具体体现。
本文出自:谁不小心的csdn博客inode结构成员详解
inode结构体成员详解的更多相关文章
- go语言之行--结构体(struct)详解、链表
一.struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程).struct的成员(也叫属性或字段)可以是任何类型,如普通类型.复合类型.函数.map.int ...
- IPv4地址结构体sockaddr_in详解
sockaddr_in结构体定义 struct sockaddr_in { sa_family_t sin_family; //地址族(Address Family) uint16_t sin_por ...
- 结构体指针,C语言结构体指针详解
结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过“结构体变量名.成员名”的方式引用结构体变量中的成员,除了这种方法之外还可以使用指针. 前面讲过,& ...
- Solidity的自定义结构体深入详解
一.结构体定义 结构体,Solidity中的自定义类型.我们可以使用Solidity的关键字struct来进行自定义.结构体内可以包含字符串,整型等基本数据类型,以及数组,映射,结构体等复杂类型.数组 ...
- struct stat结构体的详解和用法
[cpp] view plaincopy //! 需要包含de头文件 #include <sys/types.h> #include <sys/stat.h> S_ISLNK( ...
- (C语言)结构体成员的引用->(箭头)和 .(点)
关于结构体成员的引用有这样的规律: 箭头(->):左边必须为指针: 点号(.):左边必须为实体. 那么如果一个结构体指针引用一个成员,这个成员又是一个结构体(并且是一个实体),那么如果要引用这个 ...
- Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- C语言中访问结构体成员时用‘.’和‘->’的区别
举个例子,定义了一个叫Student,别名为stu的结构类型,我们声明了一个结构体变量叫stu1,声明了一个结构体指针为stuP. typedef struct Student { char name ...
- C基础--结构体成员初始化方式
之前在linux内核代码中看到结构体成员成员初始化使用类似于.owner = THIS_MODULE, 不太见过,于是搜了个博客,分享下: 转自:http://www.cnblogs.com/Anke ...
随机推荐
- CentOS6.5 下在Nginx中添加SSL证书以支持HTTPS协议访问
参考文献: 1. NginxV1.8.0安装与配置 2. CentOS下在Nginx中添加SSL证书以支持HTTPS协议访问 3. nginx配置ssl证书的方法 4.nginx强制使用https访问 ...
- Centos6.5快速配置可用网卡
原文链接: Centos6.5快速配置可用网卡 安装完成后,我们启动我们的系统,此时我们的系统,是没有连网的,IP设备,并没有被激活,如果我们使用ifconfig命令查看IP地址,就会发现,此刻的地址 ...
- 同步fifo的verilogHDL设计实例
原创 设计一个fifo,输入16bit,输出16bit的data,寻址宽度5bit,有空满标志. top 层如下所示: /* date : 2014/10/14 version : modelsim ...
- oracle中if/else
oracle中if/else功能的实现的3种写法 1.标准sql规范 一.单个IF 1. if a=... then ......... end if; 2. if a=... then .... ...
- Spring IOC(DI)之注入方式
一次被问到IOC的注入方式,当时脑袋一阵混乱,不知道噻.于是google了一下,发现众说纷纭,有说三种的,有说四种的.都滚犊子吧,还是看看官方文档吧. DI exists in two major v ...
- Android Support Library更新到v22.1之AppCompat新特性
构建一个可以跑在不同版本 Android 平台的软件,是非常复杂和耗时的.为了解决这个问题,Android 推出了 Android Support Library (安卓兼容包),让新的UI控件也可以 ...
- ios中的任务分段
工作比较忙,蛮久没有写东西了,今天我要写的是ios中的任务分段.大多数的情况下,我们用不到任务分段,但是如果我们是在执行比较频繁的函数或者这个函数是比较耗时, 某一条件下,我要执行新的任务,并且取消上 ...
- [Android] FileInputStream跟踪
1. 源起 需要跟踪FileInputStream的Read的Nativie实现,开始走了弯路,Java工程下的FileInputStream实现与Android工程的实现不同.另外,http://b ...
- ACM比赛(11462 Age Sort)
You are given the ages (in years) of all people of a country with at least 1 year of age. You know t ...
- 再写KMP算法
#include<iostream> #include<string> using namespace std; void getNext(char const*T,int l ...