inode结构体成员详解
2013-07-17 20:03
399 查看
概述:inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间、档名、使用者及群组等。inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inode。在阅读文件系统源码的时候,必须对这个结构有着清醒的认识。下面分别对VFS inodee与Ext2 inode做一下简单的描述:
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:
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结构成员详解
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结构成员详解
相关文章推荐
- 结构体struct的成员变量字节对齐问题详解
- 详解C语言的结构体中成员变量偏移问题
- termios 结构体各成员 详解及设置
- 由结构体成员地址计算结构体地址——list_entry()原理详解
- task_struct结构体成员详解
- termios 结构体各成员 详解及设置
- 由结构体成员地址计算结构体地址——节点地址的函数list_entry()原理详解
- Linux_Struct_inode() 结构体详解
- termios 结构体各成员 详解及设置
- 阅读Linux设备驱动模型源码之 device结构体成员详解
- struct inode 结构体详解
- Linux_Struct_inode() 结构体详解
- 3.c语言结构体成员内存对齐详解
- Java并发——Executor框架详解(Executor框架结构与框架成员)
- 结构体字节对齐详解
- 结构体struct 名称定义详解
- 参考,灵活数组成员,可变长结构体或者FAQ里下标为0的数组
- C 结构体 struct 详解
- C/C++疑问之存取结构体成员的点运算符(.)和箭头运算符(->)的区别
- 结构体中四字节对齐的详解