• VFS四大struct:file、dentry、inode、super_block


    VFS四大struct:file、dentry、inode、super_block

    dentry

    dentry有什么作用?dentry保存了目录/文件到inode的映射,在open一个文件时,如果路径上的某个目录或者最后的文件没有对应的dentry,则会为其建立dentry并插入dentry hashtable,dentry里的d_inode成员保存了该目录文件/文件的indoe指针。这样后面如果在lookup这个目录/文件时就可以根据目录/文件的hash值/name等找到对应的dentry,找到了对应的dentry后,则就知道了这个目录文件/文件的inode struct,就不用再进入文件系统层面去lookup这个目录/文件了,如果是进入到文件系统层面去lookup了,会去读目录文件lookup,而这个涉及到读IO,比较耗时。

    dentry其实是包含路径含义的,比如说某个目录/文件的dentry,这里说的目录/文件是需要有其完整的路径的,比如/data/test/foo目录,/data/test/foo/bar.txt文件,因为dentry的hash值是根据其父目录的dentry和目录名/文件名两者计算出来的。

    • d_name: qstr struct,里面存储了此dentry的hash值,此hash值用于在dentry hashtable上查找匹配;里面的name成员指向d_iname成员数组
    • d_parent:此dentry的parent dentry
    • d_iname: 保存的目录或者文件的名字,这个名字不包含路径,这个数组的大小是32(CONFIG_64BIT defined case)
    struct dentry {
        /* RCU lookup touched fields */
        unsigned int d_flags;        /* protected by d_lock */
        seqcount_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 */
    
        /* Ref lookup also touches following */
        struct lockref d_lockref;    /* per-dentry lock and refcount */
        const struct dentry_operations *d_op;
        struct super_block *d_sb;    /* The root of the dentry tree */
        unsigned long d_time;        /* used by d_revalidate */
        void *d_fsdata;            /* fs-specific data */
    
        union {
            struct list_head d_lru;        /* LRU list */
            wait_queue_head_t *d_wait;    /* in-lookup ones only */
        };
        struct list_head d_child;    /* child of parent list */
        struct list_head d_subdirs;    /* our children */
        /*
         * d_alias and d_rcu can share memory
         */
        union {
            struct hlist_node d_alias;    /* inode alias list */
            struct hlist_bl_node d_in_lookup_hash;    /* only for in-lookup ones */
             struct rcu_head d_rcu;
        } d_u;
    } __randomize_layout;

    file struct

    表示一个file

    • f_path: 一个path结构体,这个path结构体里保存了这个文件的dentry,根据dentry又可以得到inode struct。path结构体里还有file所在的文件系统对应的vfs_mount struct;
    • f_op:很重要的成员,read/write等系统调用就是根据这个file_operations来调用具体文件系统的file_operations函数;
    struct file {
        union {
            struct llist_node    fu_llist;
            struct rcu_head     fu_rcuhead;
        } f_u;
        struct path        f_path;
        struct inode        *f_inode;    /* cached value */
        const struct file_operations    *f_op;
    
        /*
         * Protects f_ep_links, f_flags.
         * Must not be taken from IRQ context.
         */
        spinlock_t        f_lock;
        enum rw_hint        f_write_hint;
        atomic_long_t        f_count;
        unsigned int         f_flags;
        fmode_t            f_mode;
        struct mutex        f_pos_lock;
        loff_t            f_pos;
        struct fown_struct    f_owner;
        const struct cred    *f_cred;
        struct file_ra_state    f_ra;
    
        u64            f_version;
    #ifdef CONFIG_SECURITY
        void            *f_security;
    #endif
        /* needed for tty driver, and maybe others */
        void            *private_data;
    
    #ifdef CONFIG_EPOLL
        /* Used by fs/eventpoll.c to link all the hooks to this file */
        struct list_head    f_ep_links;
        struct list_head    f_tfile_llink;
    #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
        errseq_t        f_wb_err;
    } __randomize_layout
      __attribute__((aligned(4)));    /* lest something weird decides that 2 is OK */
    

    struct inode

    文件目录都会有inode(目录也是一种文件,目录文件里的内容是其子目录/文件名及其inode number)

    • i_fop,这个成员将会被赋值给file struct f_op成员,成为file struct里的file_operations函数集;
    • i_ino,file inode number
    struct inode {
        umode_t            i_mode;
        unsigned short        i_opflags;
        kuid_t            i_uid;
        kgid_t            i_gid;
        unsigned int        i_flags;
    
    #ifdef CONFIG_FS_POSIX_ACL
        struct posix_acl    *i_acl;
        struct posix_acl    *i_default_acl;
    #endif
    
        const struct inode_operations    *i_op;
        struct super_block    *i_sb;
        struct address_space    *i_mapping;
    
    #ifdef CONFIG_SECURITY
        void            *i_security;
    #endif
    
        /* Stat data, not accessed from path walking */
        unsigned long        i_ino;
        /*
         * Filesystems may only read i_nlink directly.  They shall use the
         * following functions for modification:
         *
         *    (set|clear|inc|drop)_nlink
         *    inode_(inc|dec)_link_count
         */
        union {
            const unsigned int i_nlink;
            unsigned int __i_nlink;
        };
        dev_t            i_rdev;
        loff_t            i_size;
        struct timespec64    i_atime;
        struct timespec64    i_mtime;
        struct timespec64    i_ctime;
        spinlock_t        i_lock;    /* i_blocks, i_bytes, maybe i_size */
        unsigned short          i_bytes;
        u8            i_blkbits;
        u8            i_write_hint;
        blkcnt_t        i_blocks;
    
    #ifdef __NEED_I_SIZE_ORDERED
        seqcount_t        i_size_seqcount;
    #endif
    
        /* Misc */
        unsigned long        i_state;
        struct rw_semaphore    i_rwsem;
    
        unsigned long        dirtied_when;    /* jiffies of first dirtying */
        unsigned long        dirtied_time_when;
    
        struct hlist_node    i_hash;
        struct list_head    i_io_list;    /* backing dev IO list */
    #ifdef CONFIG_CGROUP_WRITEBACK
        struct bdi_writeback    *i_wb;        /* the associated cgroup wb */
    
        /* foreign inode detection, see wbc_detach_inode() */
        int            i_wb_frn_winner;
        u16            i_wb_frn_avg_time;
        u16            i_wb_frn_history;
    #endif
        struct list_head    i_lru;        /* inode LRU list */
        struct list_head    i_sb_list;
        struct list_head    i_wb_list;    /* backing dev writeback list */
        union {
            struct hlist_head    i_dentry;
            struct rcu_head        i_rcu;
        };
        atomic64_t        i_version;
        atomic64_t        i_sequence; /* see futex */
        atomic_t        i_count;
        atomic_t        i_dio_count;
        atomic_t        i_writecount;
    #ifdef CONFIG_IMA
        atomic_t        i_readcount; /* struct files open RO */
    #endif
        const struct file_operations    *i_fop;    /* former ->i_op->default_file_ops */
        struct file_lock_context    *i_flctx;
        struct address_space    i_data;
        struct list_head    i_devices;
        union {
            struct pipe_inode_info    *i_pipe;
            struct block_device    *i_bdev;
            struct cdev        *i_cdev;
            char            *i_link;
            unsigned        i_dir_seq;
        };
    
        __u32            i_generation;
    
    #ifdef CONFIG_FSNOTIFY
        __u32            i_fsnotify_mask; /* all events this inode cares about */
        struct fsnotify_mark_connector __rcu    *i_fsnotify_marks;
    #endif
    
    #if IS_ENABLED(CONFIG_FS_ENCRYPTION)
        struct fscrypt_info    *i_crypt_info;
    #endif
    
        void            *i_private; /* fs or device private pointer */
    } __randomize_layout;
  • 相关阅读:
    个人亲历运维面试
    《Kubernetes进阶实战》之管理Pod资源对象
    Docker容器必备技能 -- iptables
    vue后台管理权限正确思路
    Axios 各种请求方式传递参数格式
    Cookie的使用(js-cookie插件)
    微信小程序template模板与component组件的区别和使用
    如何机智地回答浏览器兼容性问题
    webpack系列5:源码流程,webpack编译流程
    webpack系列4:文件分析.
  • 原文地址:https://www.cnblogs.com/aspirs/p/15737589.html
Copyright © 2020-2023  润新知