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

目录

8.3 VFS结构

8.3.3 特定进程信息

8.3.4 文件操作


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

8.3 VFS结构

8.3.3 特定进程信息

如何关联 fd 与 inode 两者?

        1. fd作为 fd_array[ ] 数组的索引,可找到struct file。

        2. 再通过 struct file 成员 f_inode 得到 struct inode。

struct    task_struct {

        int            link_count,total_link_count;         // 防止链表无限循环。

        struct  fs_struct            fs;             //文件系统信息。

        struct  files_struct     *files;         // 指向一个 struct file 数组。

        struct  nsproxy            *nsproxy;  // 其中包含 mnt_namespace

}

struct    files_struct {

        struct   fdtable __rcu         *fdt;

        struct   fdtable                 fdtab;

        int                                      next_fd;                               // 下一次open文件时使用的fd

        unsigned long                   close_on_exec_init[1];         // close_on_exec 的初始化值

        unsigned long                   open_fds_init[1];                  // open_fds 的初始化值

        struct file                            *fd_array[ NR_OPEN_DEFAULT ];  // 具体所有打开的文件

};

struct    fdtable {

        unsigned int         max_fds;         // 该进程可处理的最大fd数目。

        struct file __rcu  **fd;                 // fd作为该数组的索引。

        unsigned long      *close_on_exec;

                // 位图,表示exec时关闭哪些文件描述符。用 close_on_exec_init 初始化。

        unsigned long      *open_fds;

                //位图,表示当前所有打开的 fd。用 open_fds_init 初始化该成员。

};

struct   file:表示一个打开的文件。

struct   file {

        struct path           f_path;

                //包含 struct dentry,dentry 包含文件名和 inode 关联信息。

        

        struct inode         *f_inode;                 //该文件对应的 inode。

        struct file_operations         *f_op;       // 该文件的操作函数。

        unsigned int         f_flags;

                //标志有:O_NONBLOCK、O_TRUNC,O_CREAT,O_CLOEXEC。

        

        fmode_t               f_mode;         // 打开文件的模式(读,写)。

        loff_t                     f_pos;           // 文件当前位置。

        struct fown_struct         f_owner;         // 该文件所属进程信息。

        struct file_ra_state        f_ra;               // 文件预读信息。

        void                               *private_data;

        struct address_space       *f_mapping;         // 文件映射。

}

struct file 和 struct inode 都包含 struct address_space:

        file->f_mapping  被设置为 inode->i_mapping。

                file->f_mapping   =   inode->i_mapping;

struct    path {

        struct vfsmount         *mnt;            // 文件系统挂载信息。

        struct dentry            *dentry;         // 目录项,包含文件名,目录层次信息。

}

struct dentry:

        存储文件名和目录层次结构信息,可快速查找对应inode。

struct    dentry {

        struct dentry        *d_parent;

        struct qstr            d_name;         // 文件名。

        struct inode         *d_inode;         // 文件inode。

        ...

}

struct super_block 中 struct list_head    s_list成员:

        作用:连接所有超级块。

        list_add_tail(&s->s_list, &super_blocks);

struct file -> path -> dentry -> 文件名/目录层次

struct file -> inode

8.3.4 文件操作

每个 struct file 包含一个 struct file_operations 函数指针。

        通常属性相同的两个文件,对应的struct file_operations相同。

struct     file_operations {

        struct module    *owner;         // 当以模块形式编译文件系统时使用。

        int           (*open) (struct inode *, struct file *);         

                // 打开文件。将 file 关联到 inode。

        ssize_t    (*read) (struct file *, char __user *, size_t, loff_t *);

        ssize_t    (*write) (struct file *, const char __user *, size_t, loff_t *);

        loff_t        (*llseek) (struct file *, loff_t, int);

        __poll_t   (*poll) (struct file *, struct poll_table_struct *);         

                // 用于实现IO多路复用。

        long         (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

                //和硬件通信,只能用于设备文件(/dev/*)

        long         (*compat_ioctl) (struct file *, unsigned int, unsigned long);

        int            (*mmap) (struct file *, struct vm_area_struct *);

                //将文件内容映射到进程虚拟地址空间。

        int            (*flush) (struct file *, fl_owner_t id);

                //关闭文件时调用。网络文件系统用来来标记传输结束。

        int            (*release) (struct inode *, struct file *);

                // file引用计数为0,调用release。

        int            (*fsync) (struct file *, loff_t, loff_t, int datasync);

                //同步内存文件到磁盘。

        int            (*fasync) (int, struct file *, int);

                //通过信号通知进程文件发生改变。fsync

        unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

 

        int         (*flock) (struct file *, int, struct file_lock *);

        int         (*fadvise)(struct file *, loff_t, loff_t, int);

};

lock:在内核中实现的文件锁机制。

flock:给用户空间实现的 POSIX 文件锁机制。

对于不同文件,只实现需要的函数,不需要的函数为 NULL。

        如 PIPE 文件不需要 readdir 函数,指向 NULL 即可。

设备文件的操作函数:

        struct file_operations         def_blk_fops;

Ext3文件系统的文件的操作函数:

        struct file_operations         ext3_file_operations;

struct file_operations         ext3_file_operations = {

        .llseek = generic_file_llseek,

        .read = do_sync_read,

        .write = do_sync_write,

        .unlocked_ioctl = ext3_ioctl,

        .mmap = generic_file_mmap,

        .open = dquot_file_open,

};

以generic_前缀开头的函数,表示是VFS通用函数。

1. 目录信息

struct     task_struct {

        struct fs_struct        *fs;         //文件系统的属性。

        struct nsproxy         nsproxy;

}

struct    fs_struct {

        int                       umask;

                //创建新文件的权限掩码,可用 umask 命令读写。

        struct path         root;

                //该进程的根目录,chroot 命令可改变。

        struct path         pwd;

                //该进程的 PWD 显示目录。cd 和 chdir 命令可改变。

        ...

}

2. VFS 命名空间

每个容器都需要记录各自装载的文件系统。

CLONE_NEWNS 标志:

        fork时将创建新的命名空间,而不继承父进程的命名空间。

struct    nsproxy {

        ...

        struct mnt_namespace         *mnt_ns;         // VFS 命名空间。

}

struct    mnt_namespace {

        atomic_t                 count;         // 使用该命名空间的进程数目。

        struct mount           *root;         // 指向根目录。

        struct list_head       list;            // 该命名空间中所有文件系统的 mount 实例。

        ...

};

相关推荐

  1. 8 虚拟文件系统3

    2024-07-19 17:16:02       20 阅读
  2. 8-网络设备文件管理

    2024-07-19 17:16:02       49 阅读
  3. Linux虚拟文件系统

    2024-07-19 17:16:02       52 阅读
  4. MySQL 高级 - | 配置文件系统变量

    2024-07-19 17:16:02       22 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 17:16:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 17:16:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 17:16:02       58 阅读
  4. Python语言-面向对象

    2024-07-19 17:16:02       69 阅读

热门阅读

  1. linux yum,rpm,dkpg,apt区别

    2024-07-19 17:16:02       20 阅读
  2. 【C++】C++中find_first_of函数解析

    2024-07-19 17:16:02       19 阅读
  3. PHP MySQL 读取数据

    2024-07-19 17:16:02       18 阅读
  4. Handler续谈(epoll)

    2024-07-19 17:16:02       17 阅读
  5. Git提交到错误分支怎么办?(解决办法)

    2024-07-19 17:16:02       21 阅读
  6. 在ubuntu系统上安装qt 2

    2024-07-19 17:16:02       19 阅读
  7. CONFIG_MTD_SPI_NOR_USE_4K_SECTORS

    2024-07-19 17:16:02       21 阅读
  8. 网络通信协议

    2024-07-19 17:16:02       13 阅读