与 索引节点inode对象关联的方法称为索引节点操作,由struct inode_operations 结构体描述,该结构的地址存放在inode结构体域变量i_op字段中,struct inode_operations具体描述如下:
struct inode_operations { struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); void * (*follow_link) (struct dentry *, struct nameidata *); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct dentry *, struct nameidata *, void *); int (*create) (struct inode *,struct dentry *,int, struct nameidata *); int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); int (*symlink) (struct inode *,struct dentry *,const char *); int (*mkdir) (struct inode *,struct dentry *,int); int (*rmdir) (struct inode *,struct dentry *); int (*mknod) (struct inode *,struct dentry *,int,dev_t); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); void (*truncate) (struct inode *); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); 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); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); } ____cacheline_aligned;
这些方法对所有的索引节点和文件系统都是可用的。不过只有其中的一个子集应用到某一特定的索引节点或文件系统中,未实现的方法对应的字段被置为NULL。
依次分析这些函数的含义:
create(struct inode *,struct dentry *,int, struct nameidata *);
在某个目录下,为与dentry目录项相关的常规文件创建一个新的磁盘索引节点。
SYSCALL_DEFINE2(creat, const char __user *, pathname, int, mode) { return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); }
sys_create
|--sys_open
|--do_filp_open
|--path_openat
|--do_last
|--vfs_create
|--dir->i_op->create(dir, dentry, mode, nd)
lookup(struct inode *dir,struct dentry *, struct nameidata *);
查找索引节点所在的目录,这个索引节点所对应的文件名就包含在dentry目录项中。在很多地方都会用到,比如:d_inode_lookup(),d_alloc_and_lookup()
follow_link(struct dentry *, struct nameidata *);
解释inode索引节点所指定的符号链;如果该符号链是相对路径名,从指定的dir目录开始进行查找。
permission(struct inode *dir, int);
确认是否允许对inode索引节点所指的文件进行指定模式的访问。
get_acl(struct inode *, int);
readlink(struct dentry *, char __user *,int);
将dentry所指定的符号链中对应的文件路径名拷贝到buffer所指定的内存区。
put_link(struct dentry *, struct nameidata *, void *);
link(struct dentry *,struct inode *,struct dentry *);
创建一个新的名为new_dentry硬链接,这个新的硬连接指向dir目录下名为的old_dentry文件。
unlink(struct inode *,struct dentry *);
从dir目录删除dentry目录项所指文件的硬链接
symlink(struct inode *,struct dentry *,const char *);
在某个目录下,为与目录项相关的符号链创建一个新的索引节点
mkdir(struct inode *,struct dentry *,int);
在某个目录下,为与目录项对应的目录创建一个新的索引节点。
rmdir(struct inode *,struct dentry *);
从一个目录中删除子目录。子目录的名称包含在目录项对象中
mknod(struct inode *,struct dentry *,int,dev_t);
在dir目录下,为与目录项对象相关的特殊文件创建一个新的磁盘索引节点。其中参数mode 和 rdev分别表示文件的类型和该设备的主码。
rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
将old_dir目录下的文件 old_dentry移到new_dir目录下,新文件名包含在 new_dentry指向的目录项中
truncate(struct inode *);
修改索引节点inode所指文件的长度。在调用该方法之前,必须将inode对象的i_size域设置为需要的新长度值。
setattr(struct dentry *, struct iattr *);
设置目录项的属性
getattr(struct vfsmount *mnt, struct dentry *, struct kstat *);
获得目录项的属性
setxattr(struct dentry *, const char *,const void *,size_t,int);
设置目录项的扩展属性(扩展属性存放在任何索引节点之外的磁盘块中)
getxattr(struct dentry *, const char *, void *, size_t);
获取目录项的扩展属性
listxattr(struct dentry *, char *, size_t);
获取扩展属性名称的整个链表
removexattr(struct dentry *, const char *);
删除索引节点的扩展属性
truncate_range(struct inode *, loff_t, loff_t);
fiemap(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);