深入理解linux内核读书笔记 -- 虚拟文件系统 -- vfs的数据结构,超级块/索引节点(inode)/文件/目录项对象介绍+字段介绍+方法表,文件/目录项对象高速缓存,如何更新缓存

目录

12章 - 虚拟文件系统 - vfs的数据结构

超级块对象(super_block)

介绍

字段

字段介绍 

super_operations表

限额系统 

索引节点对象(inode)

介绍

字段

字段介绍 

inode_operations表

文件对象

介绍

字段 

字段介绍 

filp_cachep(slab高速缓存)

介绍

file_operationa表

目录项对象

引入

介绍

四种状态 

字段

字段介绍

inode和目录项对象的关联

dentry_operations表

目录项高速缓存 

引入

组成

​编辑

介绍

更新缓存


12章 - 虚拟文件系统 - vfs的数据结构

下图是vfs结构中对象的大致关系:

超级块对象(super_block)

介绍

字段

字段介绍 

所有超级块对象以双向循环链表的形式组织起来

  • 第一个元素 -- super_blocks变量
  • s_list -- 指向链表相邻元素

s_fs_info -- 指向属于具体文件系统的超级块信息

 s_op字段中存放了super_operations结构体的起始指针

  • 通过超级块对象的指针,访问其s_op字段,再在其中调用某个操作:

通常,s_fs_info指向的数据会被复制到内存

  • 方便我们操作磁盘分配位图,以便分配或释放磁盘块

但是,这样就会造成磁盘上和内存上的超级块不一样

  • 所以我们需要更新同步 -- 引入s_dirt标志,表示该超级块是否是脏的(也就是是否进行了修改数据)
  • 然后,linux还会定期将所有"脏"的超级块写回磁盘,防止突然断电/其他突发问题,导致大量数据无法写回磁盘

超级块中会存放该文件类型所有的文件对象,以双向链表的形式组织起来(文件对象在下面有介绍)

  • 这个链表包含了文件系统中所有已打开文件的文件对象

除此之外,超级块中也会存放该文件类型所有的inode对象,也是一个双向链表 ,s_inodes字段指向该链表


 

super_operations表

限额系统 

是一种系统功能,用于限制用户对系统资源的使用

索引节点对象(inode)

介绍

文件名可以随意修改,但文件和inode之间的链接一般是不变的

字段

字段介绍 

和超级块对象类似,它也可以在内存中被修改数据,也需要被更新 -- 通过i_state字段标识该inode是否脏

inode对象总是会位于下面三种双向循环链表中的一种:

  • 其中,i_list也是指向相邻元素

除了上面三种,所有的inode对象还会位于一个散列表中,但这个散列表具有前后指针,所以形成了一个双向链表结构

  • 通过i_hash可以拿到该结构

索引节点对象也包含在per-filesystem的链表中

  • per-filesystem通常用来描述针对每个文件系统的特定操作或数据结构
  • 我猜这里指的是 -- inode会存放在对应的文件系统下的对象中,比如超级块对象(超级块对象正是管理整个文件系统的结构,那么它里面存放所有该类文件系统的inode对象也不奇怪了)

链表头存放在s_inodes(超级块对象中的字段):

相邻指针存放在inode中的i_sb_list

和超级块对象类似,也有存放索引节点操作的表,表现形式为inode_operations结构

  • i_op字段存放了该结构的指针

i_fop字段存放了该文件类型的默认文件操作

i_dentry字段 指向包含该文件名的目录项对象

  • 有助于快速定位到文件的目录项,进而进行文件访问和管理
  • (早在之前,我们就已经介绍过,在目录文件的数据块里,会存放文件名和inode的映射关系,通过该字段,可以定位到相关目录项对象,然后拿到文件名到 inode 的映射关系)

inode_operations表

和超级块类似:

文件对象

介绍

一个完全是软件层的结构

  • 主要存储了文件的访问信息,可以有效地跟踪和管理进程对文件的访问,确保文件的一致性和安全性

字段 

 

字段介绍 

f_pos字段记录了当前的文件偏移量(也就是文件指针当前指向的读写位置)

  • 因为存在多个进程打开同一个文件的情况
  • 为了保证访问的安全性,文件指针必须是每个进程一个(也就是放在文件对象里),而不能在inode对象里(因为会共享一个inode)

还记得上面在超级块字段中介绍的s_files指针吗,它指向[由该文件系统所有文件对象]组织起来的双向链表

  • 而前后指针存放在文件对象的f_list字段中:

  • 这也是为什么父子进程中,父进程/子进程关闭某一文件,另一方依然可以使用它的原因 -- 因为它此时的引用计数并不等于0
  • 而线程之间共享的文件就不行,因为他们是真正意义上的共享,引用计数不会因为线程的创建而增多,所以一旦其中一方关闭,其他线程就无法操作该文件了

filp_cachep(slab高速缓存)

介绍

也就是说,linux会从内存池中分配file对象:

并且有一个申请的上限值:

 和其他对象一样,文件对象也有一个操作方法表

  • 也就是说,当进程打开某一文件时,会从该文件对应的inode中拿到i_fop字段,然后用这个字段初始化该文件的文件对象中的f_op字段
  • 之后,对该文件的操作方法就可以从f_op字段指向的表中调取了(至于为什么是用f_op,我感觉是因为用户直接操作的就是文件对象指针)
  • 当然,也可以通过f_op来修改表中的函数指针,从而自定义文件操作

file_operationa表

和前面的对象类似:

目录项对象

引入

--启动块,块组介绍,超级块,inode表,inode,数据块(块大小,文件和数据块的对应),文件名存放位置(如何写入/读取目录,如何查找文件),块位图,inode位图,块组描述符表,文件系统的格式化_group descriptor table-CSDN博客

我们之前探讨过文件名和inode的关系,最终得出,目录文件中会存放文件名与inode的映射关系

  • 其实也就是这里即将要介绍的目录项对象 -- 它会存放文件名与对应inode的映射关系

介绍

和文件对象相对的,目录也有自己专门的对象类型

  • 每个目录项对象代表文件系统中的一个文件名或目录名,它指向一个特定的 inode,该 inode 包含了文件的实际内容和元数据信息

和文件对象类似,他也是一个纯软件层的结构,在磁盘中没有对应的映像

除此之外,它也是通过slab高速缓存分配空间的

四种状态 

每个目录项对象可以处于以下四种状态之一:

字段

字段介绍

和前面几种对象类似,目录项对象也有自己的方法表

正在使用的目录项对象被组织成一个双向链表

  • 目录项对象中的d_alias字段存放该链表中相邻元素的地址 
inode和目录项对象的关联

inode中的i_dentry字段

  • 指向该链表中对应的目录项对象(这个目录项对象记录了文件名和与之相关联的 inode 号)
  • 由于一个inode可以与多个文件名(也可以叫做硬链接)相关联,所以需要一个链表将它们组织起来
  • d_alias字段 -- 指向链表中的相邻元素

目录项对象中的d_inode字段

  • 指向与该目录项对象相关联的 inode,表示该目录项对象代表的文件的元数据信息
  • 如果一个目录项对象仍然存在于文件系统中,但它指向的文件已经没有任何硬链接,此时他就是负状态,会被移动到LRU链表中,并随着链表移动,最终被释放

目录项对象会被组织成哈希表的形式,以便快速地进行文件名查找和访问

  • d_hash字段指向该链表的结点

dentry_operations表

目录项高速缓存 

引入

组成

介绍

可以作为inode高速缓存的控制器

  • 如果目录项高速缓存仍在使用这些inode,就会将inode放入ram中,以便快速访问
更新缓存

会根据插入时间的顺序将未使用的目录项对象组织成双向链表

  • 先将早已插入的目录项对象释放,留下新一点的对象
  • 该双向链表的首尾地址存放在dentry_unused变量中
  • 目录项对象的d_lru字段 -- 存放该链表中相邻目录项对象的指针

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值