ILD

data structures in vfs
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2025-1-12 站点:Inside Linux Development

Inodes - indexing files and directories

存储文件和和目录的节点信息。定义在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 operations

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和文件名。

其它的文件操作函数,比如创建、删除、移动等,都定义在这个结构体里面。


Tracking file data on disk through inodes

inode存在文件系统的inode table中。inode对应的文件的内容,存在13个direct block指针,1个single indirec指针 ,

1个double indirect指针,1个triple indirect指针。


13个direct指针,只能使用13个block。如果存不下,依次使用1级、2级、3级指针。


Directory entries - mapping inodes to filenames

inode包含很多metadata,但是它并不包含name。文件名包含在目录的内容中。目录映射它所有的子文件名到对应的inode,这个过程叫做linking。

vfs的操作目标通常是路径,路径需要一级级执行inode的lookup操作,找到对应的inode。找到inode后,就可以读取文件属性、读写文件内容。


内核缓存了lookup的结果,叫做dentry object。路径中的每一个component都是一个dentry object。


dentry cache

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。


dentry operations

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 objects - representing open files

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;
}


Defining file operations

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 *);
}


Superblocks - describing filesystem metadata

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;

}


superblock operations

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/


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.