索引节点对象包含了内核在操作文件或目录时需要的全部信息。对于Unix风格的文件系统来说,这些信息可以从磁盘索引节点直接读入。如果一个文件系统没有索引节点,不管这些相关信息在磁盘上是怎么存放的(没有索引节点的文件系统通常将信息作为文件的一部分存储起来,有些现代文件系统使用数据库来存储文件的数据。不管是那种方式索引节点对象必须在内核中创建以便文件系统使用),文件系统都必须从中提取这些信息。
索引节点对象由inode结构体表示:
- 在<Fs.h(include/linux)>中
- struct inode {
- struct hlist_node i_hash; /* 散列表 */
- struct list_head i_list; /* 索引节点链表 */
- struct list_head i_sb_list; /* */
- struct list_head i_dentry; /* 目录项链表 */
- unsigned long i_ino; /* 节点号 */
- atomic_t i_count; /* 引用计数 */
- unsigned int i_nlink; /* 硬链接数 */
- uid_t i_uid; /* 使用者的id */
- gid_t i_gid; /* 使用者的组id */
- dev_t i_rdev; /* 实设备标识符 */
- unsigned long i_version; /*版本号 */
- loff_t i_size; /* 以字节为单位的文件大小 */
- #ifdef __NEED_I_SIZE_ORDERED
- seqcount_t i_size_seqcount;
- #endif
- struct timespec i_atime; /* 最后访问时间 */
- struct timespec i_mtime; /* 最后修改时间 */
- struct timespec i_ctime; /* 最后改变时间 */
- unsigned int i_blkbits; /* 以位为单位的块大小 */
- blkcnt_t i_blocks; /* 文件的块数 */
- unsigned short i_bytes; /* 使用的字节数 */
- umode_t i_mode; /* 访问控制权限 */
- spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
- struct mutex i_mutex; /* */
- struct rw_semaphore i_alloc_sem; /* 嵌入在i_sem内部 */
- const struct inode_operations *i_op; /* 索引节点操作表 */
- const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
- struct super_block *i_sb; /* 相关的超级块 */
- struct file_lock *i_flock; /* 文件锁链表 */
- struct address_space *i_mapping; /* 相关的地址映射 */
- struct address_space i_data; /* 设备地址映射 */
- #ifdef CONFIG_QUOTA
- struct dquot *i_dquot[MAXQUOTAS]; /* 节点磁盘限额 */
- #endif
- struct list_head i_devices; /* 块设备链表 */
- union {
- struct pipe_inode_info *i_pipe; /* 管道信息 */
- struct block_device *i_bdev; /* 块设备驱动 */
- struct cdev *i_cdev; /* */
- };
- int i_cindex; /* */
- __u32 i_generation; /* 索引节点版本号 */
- #ifdef CONFIG_DNOTIFY
- unsigned long i_dnotify_mask; /* Directory notify events */
- struct dnotify_struct *i_dnotify; /* for directory notifications */
- #endif
- #ifdef CONFIG_INOTIFY
- struct list_head inotify_watches; /* watches on this inode */
- struct mutex inotify_mutex; /* protects the watches list */
- #endif
- unsigned long i_state; /* 状态标志 */
- unsigned long dirtied_when; /* jiffies of first dirtying */
- unsigned int i_flags; /*文件系统标志 */
- atomic_t i_writecount;
- #ifdef CONFIG_SECURITY
- void *i_security; /* 安全模块 */
- #endif
- void *i_private; /* fs or device private pointer */
- };
一个索引节点代表文件系统中(虽然索引节点仅当文件被访问时,才在内存中创建)的一个文件,它也可以是设备或管道这样的特殊文件。因此索引节点结构体中有一些和特殊文件相关的项。
- 索引节点操作
索引节点对象中的inode_operations描述了VFS用以操作索引节点对象的所有方法:
- 在<Fs.h(include/linux)>中
- struct inode_operations {
- /* VFS通过系统调用create()和open()来调用该函数从而为dentry对象创建一个新的索引节点。 */
- int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
- /* 该函数在特定目录中找索引节点,该索引节点要对应与dentry中给出的文件名 */
- struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
- /* 该函数被系统调用link()调用,用来创建硬链接。硬链接名称由dentry参数指定,连接对象是inode结构中old_dentry目录项所代表的文件 */
- int (*link) (struct dentry *,struct inode *,struct dentry *);
- /* 该函数被系统调用unlink()调用,从inode结构中的删除由dentry结构指定的索引节点对象 */
- int (*unlink) (struct inode *,struct dentry *);
- /* 该函数被系统调用symlink()调用,创建符号链接。该符号连接名由symname指定,链接对象是inode结构中的dentry结构 */
- int (*symlink) (struct inode *,struct dentry *,const char *);
- /* 该函数被系统调用mkdir()调用,创建一个新目录。 */
- int (*mkdir) (struct inode *,struct dentry *,int);
- /* 该函数被系统调用rmdir()调用,删除inode结构中的dentry结构代表的文件 */
- int (*rmdir) (struct inode *,struct dentry *);
- /*该函数被系统调用mknod()调用,创建特殊文件 */
- int (*mknod) (struct inode *,struct dentry *,int,dev_t);
- /* VFS调用该函数来移动文件。第一参数是文件源路径,第二参数是源文件,第三参数是目标路径,第四参数是目标文件 */
- int (*rename) (struct inode *, struct dentry *,
- struct inode *, struct dentry *);
- /* 该函数被系统调用readlink()调用,拷贝数据到特定的缓冲中,拷贝的数据由dentry结构指定的符号连接 */
- int (*readlink) (struct dentry *, char __user *,int);
- /* 该函数有VFS调用,从一个符号连接查找它指向的索引节点。由dentry指向的连接被解析,其结果存放在第二个参数 */
- void * (*follow_link) (struct dentry *, struct nameidata *);
- /* 在follow_link()调用之后,该函数由VFS调用进行清除工作 */
- void (*put_link) (struct dentry *, struct nameidata *, void *);
- /* 该函数由VFS调用,修改文件大小。在调用前,索引节点的i_size项必须被设置为预期的大小 */
- void (*truncate) (struct inode *);
- /* 该函数用来检查给定的inode所代表的文件是否允许特定的访问模式 */
- int (*permission) (struct inode *, int, struct nameidata *);
- /* 该函数被notify_change()调用,在修改索引节点后,通知发生了“改变事件” */
- int (*setattr) (struct dentry *, struct iattr *);
- /* 在通知索引节点需要从磁盘中更新时,VFS会调用该函数 */
- int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
- /* 该函数被VFS调用,给dentry指定的文件设置扩展属性 */
- int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
- /* 该函数被VFS调用,第三个参数中拷贝给定文件的扩展属性(第二个参数)对应的数值 */
- ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
- /* 该函数将特定文件的所有属性列表拷贝到一个缓冲列表中 */
- ssize_t (*listxattr) (struct dentry *, char *, size_t);
- /* 该函数从给定文件中删除指定的属性 */
- int (*removexattr) (struct dentry *, const char *);
- /* */
- void (*truncate_range)(struct inode *, loff_t, loff_t);
- };