linux下VFS

  通用文件模型由下列对象类型组成:

超级块对象:存放已安装文件系统的有关信息

索引节点对象:存放关于具体文件的一般信息

文件对象:存放打开文件和进程之间交互的有关信息

目录项对象:存放目录项与对应文件进行链接的有关信息

  所有的超级块对象都以双向循环链表的形式链接在一起。

  任何基于磁盘文件系统都需要访问和更改自己的磁盘分配位图,以便分配或释放磁盘块。

  文件系统处理文件所需要的所有信息都放在一个名为索引节点的数据结构中。每个索引对象总是出现在这几个双向循环链表的某个链表中(有效未使用的索引节点链表,正在使用的索引节点链表,脏索引节点链表)

文件对象是在文件被打开时创建由file结构组成,文件对象在磁盘上没有对应的映像

文件指针必须存放在文件对象而不是索引节点对象中,文件对象通过一个名为filp的slab高速缓存分配,filp描述符地址存放在filp_cechaep(fs/file_table.c)变量中。

每个超级块对象把文件对象链表的头存放在s_file字段中,因此属于不同文件系统的文件对象就包含在不同的链表中。

当VFS代表进程必须打开一个文件时,它调用get_empty_filp()函数来分配一个新的文件对象,该函数调用kmem_cache_alloc()从filp高速缓存中获得一个空闲的文件对象。

当内核将一个索引节点从磁盘装入内存时,就会把指向这些文件操作的指针存放在file_operation结构中,该结构的地址就存放在该索引节点的i_fop字段中。

一旦目录项被存入内存,VFS就把它转换成基于dentry结构的一个目录项对象,目录项对象在磁盘上没有对应的映像,目录项对象存放在名为dentry_cache的slab分配器高速缓存中。

每个目录项对象处于四种状态之一:空闲状态,未使用状态,正在使用状态,负状态

  从磁盘读入一个目录项并构造相应的目录项对象需要花费大量的时间,在内核内存中,并不丢弃与未用目录相关的索引节点,这是由于目录项高速缓存仍在使用它们。

所有“未使用”目录项对象对存放在一个“最近最少使用LRU”的双向链表中,该链表按照插入的时间排序。

当指向相应文件的最后一个硬链接被删除之后,一个“正在使用”的目录项对象可能变成"负"状态。

每个进程都有它自己当前的工作目录和它自己的根目录。

每个进程由一个task_struct进程描述符表示,其中fs_struct代表了文件系统的信息

  struct fs_struct {
          int users;
          spinlock_t lock;
          seqcount_t seq;
          int umask;
          int in_exec;
          struct path root, pwd;
  };

files_struct代表了打开的文件的信息

  /*       
   * Open file table structure
   */      
  struct files_struct {
    /*     
     * read mostly part
     */
          atomic_t count;
          struct fdtable __rcu *fdt;
          struct fdtable fdtab;
    /*     
     * written part on a separate cache line in SMP
     */
          spinlock_t file_lock ____cacheline_aligned_in_smp;
          int next_fd;
          struct embedded_fd_set close_on_exec_init;
          struct embedded_fd_set open_fds_init;
          struct file __rcu * fd_array[NR_OPEN_DEFAULT];
  };

其中fd字段指向文件对象的指针数组,数组的索引就是文件描述符。

open_fds字段最初包含open_fds_init字段的地址,open_fds_init字段表示当前已打开文件的文件描述符的位图

当内核开始使用一个文件对象时,内核提供fget()函数以供调用,使文件对象引用计数器f_count的值增1.

文件系统注册通常在系统初始化期间并且在使用文件系统类型之前必须执行的基本操作。

特殊文件系统不限于物理块设备,然而,内核给每个安装的特殊文件系统分配一个虚拟的块设备,让其主设备号为0而次设备号具有任意值。

set_anon_super()函数用于初始化特殊文件系统的超级块,该函数本质上获得一个未使用的次设备号dev,然后使用主设备号0和次设备号dev设置新超级块的s_dev字段。

每个注册文件系统都用一个类型为file_system_type的对象来表示。

根文件系统有内核在引导阶段直接安装,并拥有系统初始化脚本以及最基本的系统程序。

通常大多数进程共享同一个命名空间,即位于系统的根文件系统且被init进程使用的已安装文件系统树.//???什么意思

linux中同一个文件系统被安装多次是可能的,不管一个文件系统被安装了多少次,都仅有一个超级块对象

对每一个安装操作,内核必须在内存中保存安装点和安装标志,以及要安装文件系统和其他已安装文件系统之间的关系,这样的信息保存在已安装文件系统描述符中,每个描述符是一个具有vfsmount类型的数据结构。

该版本下的sys_mount是原型为

 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,

                 char __user *, type, unsigned long, flags, void __user *, data)

do_mount();->do_new_mount();->do_kern_mount();->vfs_kern_mount();->mount_fs();->再调用回调函数

安装根文件系统分为两个阶段

1.安装内核特殊rootfs,该文件仅提供一个作为初始安装点的空目录

在mnt_init()函数中由init_rootfs()和init_mount_tree()完成

2.内核在空目录上安装实际根文件系统

在第二阶段reset_init();中的kernel_init();调用prepare_namespace();

rootfs特殊文件系统没有被卸载,只是隐藏在基于磁盘的根文件系统下了。

当进程必须识别一个文件时,就把它的文件路径名传递给某个VFS系统调用。

VFS系统调用的实现就完全要自己一点一点耐心的去看linux内核源码了,并不是结构和知识上的问题了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值