zoukankan      html  css  js  c++  java
  • 虚拟文件系统

    VFS的层次

    文件系统实现与用户进程(或C库)之间。

     

    文件系统分类

    基于磁盘的文件系统(ext2/3  fat  iso9660…)、虚拟文件系统(proc)、网络文件系统(nfs)

    通用文件模型

    VFS提供一种结构模型,包含了一个强大的文件系统所应具备的所有组件。所有的文件系统实现,都必须提供与VFS定义的结构配合的例程,以弥补两种试图之间的差异。

    文件描述符

    一个整数,在用户层所有有关文件的操作中用于标识一个文件,在打开文件时由内核创建,特定于进程。

    inode

    l  inode是什么?

    ²  inode用来存放文件的元数据(例如,文件的创建者、文件的创建日期、文件的大小等等)

    ²  注意inode并不包含文件名。

    l  inode的内容

    inode包含文件的元信息,具体来说有以下内容:

    ²  文件的size、文件属主的User ID、Group ID

    ²  文件的读、写、执行权限

    ²  文件的时间戳,:ctime(inode上一次变动的时间)、mtime(文件内容上一次变动的时间)、atime(文件上一次打开的时间)。

    ²  链接数,即有多少文件名指向这个inode。

    ²  文件数据分布在哪些磁盘Block。

    l  inode的状态

    每个inode处于三种状态中的一个:

    ²  inode位于内存中,未关联到文件;(inode_unused)

    ²  inode位于内存中,由一个或多个进程使用,已与磁盘同步;(inode_in_used)

    ²  inode处于活动使用状态,与磁盘上内容未同步,脏inode;

    l  inode是如何组织的?

    ²  内核使用两种方式组织inode。

    ²  链表:每个inode都有一个i_list成员,可将inode存储在链表中。(inode出现在特定于超级块的链表中i_sb_list,同时出现在特定于状态的链表中,例如inode_in_used)

    ²  散列:每个inode同时出现在一个散列表中(根据inode号快速访问inode)。

    l  目录是什么?

    ²  Linux下,目录也是文件,也有inode和数据部分,其数据部分内容如下:

    第一部分表示对应inode的编号(系统内唯一),第二部分表示文件或目录的名字。

    内核如何访问/user/bin/emacs

    首先读取根目录(这个在内核中一直被维护,),在根目录文件的数据部分查找user这个目录项,根据其中的inode编号,获取inode。bin的查找类似,一直到查找到emacs,找到emacs对应的inode,该inode的数据部分即emacs这个文件(普通数据文件)的内容。

    图示:

     

    目录项缓存dentry

    l  引入dentry

    上述访问/user/bin/emacs过程非常耗时,需要不断地读取inode和对应的数据部分。为了加速,内核将之前访问过的目录或文件(统称为目录项)缓存起来,下次再访问同样的目录项(例如,/user/bin/vi的/user/bin/部分)时,可以直接找到对应的inode(上图中为10号)。

    l  dentry的目的:

    dentry的主要用途是建立文件名和inode之间的关联。

    所以该结构体包括两个最主要的字段,d_inoded_name

    其中,d_name为文件名。qstr是内核对字符串的封装(可以理解为带有散列值的char*)。

    d_inode是与该文件名对应的inode。

    l  dentry结构体:

    struct dentry {

       

    /* Where the name belongs to - NULL is negative */

        struct inode *d_inode; 

    struct qstr d_name;

    struct dentry *d_parent; /* parent directory */

        union {

        struct list_head d_child; /* child of parent list */

        struct rcu_head d_rcu;

        } d_u;

        struct list_head d_subdirs; /* our children */

        struct dentry_operations *d_op;

        struct super_block *d_sb; /* The root of the dentry tree */

        unsignedchard_iname[DNAME_INLINE_LEN_MIN]; /* small names */

    };

    l  什么时候创建

    在VFS(以及文件系统实现)读取一个目录项(目录或普通文件)后,则创建一个dentry来缓存找到的数据。

    l  内存中这些dentry如何组织管理

    ²  结构:各个dentry实例组成了一个网络,例如,当前dentry实例对应的所有文件和子目录相关联的dentry都归入到d_subdirs中。

    ²  组织方式一:内核所有活动的dentry实例都保存在一个散列表中,该散列表使用dentry_hashtable实现(全局dentry散列表)。

    ²  组织方式二:LRU链表,长时间不使用的dentry会被删除。

    链接link

    l  两类链接:符号链接(软链接)和硬链接。

    l  符号链接(软链接)文件使用自己的inode,该inode的数据部分包含了一个字符串,给出了链接目标的路径。

    l  硬链接创建时,使用了已有的inode编号。硬链接建立以后,无法区分原来的文件和新建的硬链接文件。这种情况下,inode使用计数器来确保文件删除操作中,当没有其他文件使用该inode时,才能真正删除该inode。

    示意图:

     

    特定于进程的信息

    struct task_struct {

         ...

         /* 进程的文件系统相关的信息*/

         struct fs_struct *fs;

         /* 该进程打开的文件 */

         struct files_struct *files;

         ...

    }

    struct files_struct {

         ...

         struct fdtable fdtab;

         struct file * fd_array[NR_OPEN_DEFAULT];

    };

    struct file {

         ...

    struct path *f_path;

         loff_t   f_pos;

         ...

    };

    struct file_operations {

         ...

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

         int (*readdir) (struct file *, void *, filldir_t);

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

         int (*ioctl) (struct inode *, struct file *, unsignedint, unsignedlong);

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

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

         ...

    };

     

    struct file_operations->open函数实质上是将一个file对象关联到一个inode。

    poll函数也在其中。

    从task到dentry/inode

     

  • 相关阅读:
    洛谷 P4317
    洛谷 P6218
    洛谷 P4999
    洛谷 P2657
    CSP 2020-S2 题解
    2020CSP-S2游记
    Spring Boot中使用WebSocket总结
    防盗链
    JVM JRE和JDK的区别和联系
    Java 注解学习
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8447317.html
Copyright © 2011-2022 走看看