存储文件和和目录的节点信息。定义在include/linux/fs.h。重点关注文件系统操作相关的成员,文件的属性,只列了一个i_uid。
struct inode {
kuid_t i_uid;
const struct inode_operations *i_op;
struct super_block *i_sb;
struct address_space *i_mapping;
const struct file_operations *i_fop;
struct address_space i_data;
};
inode结构体的i_op指针,是一个inode_operations结构体指针,它定义了inode操作的函数接口。也定义在include/linux/fs.h
struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
int (*readlink) (struct dentry *, char __user *,int);
int (*create) (struct mnt_idmap *, struct inode *,struct dentry *,
umode_t, bool);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,
const char *);
int (*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,
umode_t);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,
umode_t,dev_t);
int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
struct inode *, struct dentry *, unsigned int);
int (*setattr) (struct mnt_idmap *, struct dentry *, struct iattr *);
int (*getattr) (struct mnt_idmap *, const struct path *,
struct kstat *, u32, unsigned int);
};
lookup,是查找一个目录下的文件或目录,输入参数是父目录的inode和文件名。
其它的文件操作函数,比如创建、删除、移动等,都定义在这个结构体里面。
inode存在文件系统的inode table中。inode对应的文件的内容,存在13个direct block指针,1个single indirec指针 ,
1个double indirect指针,1个triple indirect指针。
13个direct指针,只能使用13个block。如果存不下,依次使用1级、2级、3级指针。
inode包含很多metadata,但是它并不包含name。文件名包含在目录的内容中。目录映射它所有的子文件名到对应的inode,这个过程叫做linking。
vfs的操作目标通常是路径,路径需要一级级执行inode的lookup操作,找到对应的inode。找到inode后,就可以读取文件属性、读写文件内容。
内核缓存了lookup的结果,叫做dentry object。路径中的每一个component都是一个dentry object。
dentry objects定义在include/linux/dcache.h
struct dentry {
unsigned int d_flags; /* protected by d_lock */
seqcount_spinlock_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
/* --- cacheline 1 boundary (64 bytes) was 32 bytes ago --- */
};
d_inode,这个dentry对应的inode,如果dentry缓存在,那么inode也会一直缓存着。
dentry,有3个状态,used, unused, negative。nagative表示这个dentry是不存在的,其inode为NULL。
struct dentry_operations {
int (*d_revalidate)(struct dentry *, unsigned int);
int (*d_weak_revalidate)(struct dentry *, unsigned int);
int (*d_hash)(const struct dentry *, struct qstr *);
int (*d_compare)(const struct dentry *,
unsigned int, const char *, const struct qstr *);
int (*d_delete)(const struct dentry *);
int (*d_init)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_prune)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(const struct path *, bool);
struct dentry *(*d_real)(struct dentry *, enum d_real_type type);
} ____cacheline_aligned;
file object是存储在内存中的对象,用来表示一个打开的文件。file object属于process,而inode属于filesystem。
file object用file结构体表示,定义在include/linux/fs.h
struct file {
atomic_long_t f_count;
spinlock_t f_lock;
fmode_t f_mode;
const struct file_operations *f_op;
struct address_space *f_mapping;
void *private_data;
struct inode *f_inode;
unsigned int f_flags;
unsigned int f_iocb_flags;
const struct cred *f_cred;
}
file_operations结构体,包含了file object操作的接口函数,比如read/write。vfs实现了一套通用的接口
struct file_operations {
struct module *owner;
fop_flags_t fop_flags;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
}
super block存储文件系统的metadata。它是很多文件系统数据的入口,比如root inode、inode table等都可以存储在super block中。
super block在磁盘上一般存放多份,来保证super block的安全。
定义在include/linux/fs.h
struct super_block {
struct list_head s_list; /* Keep this first */
dev_t s_dev; /* search index; _not_ kdev_t */
unsigned char s_blocksize_bits;
unsigned long s_blocksize;
loff_t s_maxbytes; /* Max file size */
struct file_system_type *s_type;
const struct super_operations *s_op;
}
statfs、保存super block等接口就是定义在这个结构体中:
struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
void (*free_inode)(struct inode *);
void (*dirty_inode) (struct inode *, int flags);
int (*write_inode) (struct inode *, struct writeback_control *wbc);
int (*drop_inode) (struct inode *);
void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
int (*freeze_super) (struct super_block *, enum freeze_holder who);
int (*freeze_fs) (struct super_block *);
int (*thaw_super) (struct super_block *, enum freeze_holder who);
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
};
这篇文章没啥干货,只是罗列了一下接个结构体。
参考
https://www.geeksforgeeks.org/inode-in-operating-system/