第 8 章 虚拟文件系统(2)

目录

8.3 VFS结构

8.3.1 结构概观

8.3.2 inode


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

8.3 VFS结构

8.3.1 结构概观

VFS组成部分:

        1. 文件。

        2. 文件系统。

1. 文件的表示

        inode:包含文件信息及数据存储位置。

上图右下方:

        struct     files_struct {         //作用:跟踪该进程所有打开的文件。

                struct  file    *fd_array[ NR_OPEN_DEFAULT ];         // fd 作为索引

};

struct dentry:表示一个目录项。

        作用:缓存文件路径名。加速文件查找和访问。

底层的操作函数指针:

        1. struct    inode_operations 包括:

                创建链接,文件重命名,创建文件,删除文件。

        2. struct    file_operations 包括:

                读写文件,mmap,设置文件位置等指针。

2. 文件系统和超级块信息

超级块:struct super_block

struct super_block 包含:

        1. 文件系统信息:块长度,最大文件长度。

        2. 修改过的 inode 列表。

        3. 通过 struct super_operations    *s_op 包括操作 inode 的函数指针,如:

                alloc_inode,write_inode,destroy_inode,dirty_inode,remount_fs 等。

8.3.2 inode

inode 分为:

        存在磁盘中:存在于底层的具体文件系统中。

        存在内存中:即 struct inode(本节所讲)。

从磁盘中读取到的 inode 信息,将填充到内存 struct   inode。

应用层访问文件的过程:

        1. 路径解析。寻找对应 dentry,若未找到则创建dentry。

        2. 通过 dentry 找到对应 inode。

        3. 分配 fd 和 struct file 对象。

从Ext2开始,内核将文件属性和文件内容分开存储,分别对应 inode 和数据块 block。

struct    inode {

        umode_t           i_mode;

                // 10位,1位是文件类型,后9位是所有者/组/其他成员的读写访问权限。

        

        kuid_t           i_uid;         // 使用者 id

        kgid_t           i_gid;         // 所属组

        

        unsigned int                            i_flags;

        struct inode_operations         *i_op;

        struct super_block                 *i_sb;

        struct address_space            *i_mapping;         // 通常指向 i_data

        unsigned long         i_ino;

                //索引节点号,每个 inode 唯一,根目录的 i_ino 通常为0。

        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;         // 最后修改 inode 时间

        

        spinlock_t         i_lock;

        unsigned short             i_bytes;         // 文件中最后一个块的字节数

        u8                                 i_blkbits;       // 块大小

        blkcnt_t                         i_blocks;       // 文件占用块数,文件系统的特征。

        unsigned long               i_state;

        struct hlist_node           i_hash;

                // 连接 hash 值相等的 inode,根据 inode 号+ 超级块地址定位到 hash 表找到 inode。

        

        struct list_head                 i_io_list;

        struct list_head                 i_lru;

        struct list_head                 i_sb_list;

        struct list_head                 i_wb_list;

        union {

                struct hlist_head         i_dentry;

                        //连接了该 inode 所有 dentry,一个 inode 可有多个dentry,如硬链接。

                struct rcu_head         i_rcu;

        };

        atomic_t                             i_count;         // 使用 inode 的引用计数

        struct file_operations         *i_fop;

        struct address_space        i_data;

        union {         // 文件类型

                struct pipe_inode_info         *i_pipe;

                struct block_device              *i_bdev;

                struct cdev                            *i_cdev;

                char                                      *i_link;

                unsigned                               i_dir_seq;

        };

        void         *i_private;

};

struct   inode 中复合数据类型的成员有:

1. inode操作

即 struct inode_operations    *i_op;           

struct inode_operations    *i_op;                   操作文件的属性。

struct file_operations         *i_fop;                 操作文件的数据。

struct     inode_operations {

        struct  dentry     *(*lookup) (struct inode *,    struct dentry *,     unsigned int);

                //根据文件名查找其inode。

        char     *(*get_link) (struct dentry *,     struct inode *,     struct delayed_call *);

        int     (*readlink) (struct dentry *,     char __user *,    int);

        int     (*link) (struct dentry *,    struct inode *,    struct dentry *);

        int     (*symlink) (struct inode *,    struct dentry *,    const char *);

        int     (*unlink) (struct inode *,    struct dentry *);

        int     (*mknod) (struct inode *,    struct dentry *,    umode_t,dev_t);

        int     (*create) (struct inode *,    struct dentry *,     umode_t, bool);

        int     (*rmdir) (struct inode *,    struct dentry *);

        int     (*mkdir) (struct inode *,    struct dentry *,    umode_t);

        int     (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int);

        int     (*setattr) (struct dentry *,     struct iattr *);

                //扩展属性,实现文件ACL。

        ssize_t     (*listxattr) (struct dentry *,     char *,     size_t);

};

struct dentry 作用:

        关联文件名及其 inode。

文件ACL:

        提供比传统文件权限(user, group, others 的 rwx 权限)更细致管理。

        可对指定用户或用户组设定指定权限。

相关系统调用:

        setxattr()、getxattr()、listxattr()

命令工具:

        setfacl、getfacl

setfacl 使用举例:

        1. 赋予用户 john 读写权限:

                setfacl   -m   u:john:rw    file.txt

        2. 删除用户 jane 的所有权限:

                setfacl    -x   u:jane    file.txt

注:某些文件系统不支持ACL。

2. inode链表

一个 inode 可被包含在:

        1. 三个链表:

                1.1. inode_unused 链表:

                        该inode未关联到任何文件。

                1.2. inode_in_use 链表:

                        该inode关联到一个文件。

                1.3. 一个超级块的脏 inode 链表。

        2. 一个散列表:以支持根据 inode 编号和超级块访问 inode。

                全局数组变量:inode_hashtable

                struct    inode {

                        struct   hlist_node     i_hash;         // 用于连接 hash 冲突的 inode。

                }

struct    super_block {         // 表示文件系统的信息。

        struct list_head         s_inodes;         // 连接该文件系统所有 inode。

        struct list_head         s_dentry_lru;    // 管理 dentry 缓存的 LRU 列表。

        struct list_head         s_inode_lru;     // 管理 inode 缓存的 LRU 列表。

}

使用举例:

        list_add(&dentry->d_lru,    &dentry->d_sb->s_dentry_lru);

        dentry = list_entry(sb->s_dentry_lru.prev,    struct dentry,    d_lru);

        list_add(&inode->i_lru,    &inode->i_sb->s_inode_lru);

        inode = list_entry(sb->s_inode_lru.prev,    struct inode,    i_lru);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山下小童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值