虚拟文件系统

为了支持各种本机文件系统,且同时允许访问其他操作系统的文件,Linux 内核在用户进程与实际文件系统实现之间引入了一个抽象层,该层称为虚拟文件系统。它的任务并不简单,一方面它要提供一套管理所有文件,目录的统一方法。另一方面它要和具体文件系统支持的功能达成妥协,因为每种文件系统实现都差别迥异。

文件系统类型

文件系统一般分为如下三种:

1. 基于磁盘的文件系统,在非易失介质上存储文件的经典方法。

2. 虚拟文件系统,内核生成的虚拟结构,可用于与用户通信,比如 proc 文件系统。

3. 网络文件系统,允许通过网络访问另一台计算机上的数据。

正是因为虚拟文件系统的存在,上层应用才不会看到本地文件系统与网络文件系统的区别,它们可以通过一套统一的接口操作下层文件系统上的文件,比如打开,读,写,删除等。

通用文件模型

VFS 不仅为文件系统提供了方法和抽象,还支持文件系统中对象(或文件)的统一视图。文件这个术语的含义看起来似乎很清楚,但由于各个文件系统的底层实现不同,其语义经常有许多小而微妙的差异。并非所有文件系统都支持同样的功能,而有些操作(对“普通”文件是不可缺少的)对某些对象完全没有意义,例如集成到 VFS 中的命名管道。

并非每一种文件系统都支持 VFS 中的所有抽象。设备文件无法存储在源自其他系统的文件系统中(如FAT),后者的设计没有考虑到此类对象。

如果我们定义一个最小的通用模型,来支持内核中所有文件系统都实现的那些功能,显然不太好。因为这样会损失许多本质性的功能特性,或者导致这些特性只能通过特定文件系统访问。VFS 的方案完全相反: 提供一种结构模型,包含了一个强大文件系统所应具备的所有组件。但该模型只存在于虚拟中,必须使用各种对象和函数指针与每种文件系统适配。所有文件系统的实现都必须提供与 VFS 定义的结构配合的接口,以弥合两种视图之间的差异。

在处理文件时,内核空间和用户空间使用的主要对象是不同的。对用户程序来说,一个文件由一个文件描述符标识。该描述符是一个整数,在所有有关文件的操作中用作标识文件的参数。文件描述符是在打开文件时由内核分配,只在一个进程内部有效。两个不同进程可以使用同样的文件描述符,但二者并不指向同一个文件。基于同一个描述符来共享文件是不可能的。

内核处理文件的关键是 inode。每个文件(和目录)都有且只有一个对应的 inode,其中包含元数据(如访问权限、上次修改的日期,等等)和指向文件数据的指针。除了 inode 之外,VFS 中还有一个目录项的概念,它用来描述一个路径中的各个部分,可以代表一个目录或者文件,这里我们以 /usr/bin/emac 为例,为了查找其对应的 inode,会从 / 目录项出发,该目录项中包括它所对应的 inode,以及该目录或文件的名称。为了在其中查找 usr 目录,内核会搜索 / inode 指向的数据内容,这里包括了在 / 目录下包含的所有目录和文件。就这样,内核不断地重复上述过程就找到了目标文件对应的 inode。最后一个 inode emacs 和前三个 inode 不同,前三个都是目录,其 inode 指向的内容是目录列表,而 emacs 文件的 inode 指向的数据是文件的内容。这就是 VFS 查找一个文件的简略过程。

除了 inode 和目录项之外,VFS 中还有一个链接的概念,它用于创建文件系统对象之间的联系,有两种链接的类型,分别是软链接和硬链接。

软链接可以认为是方向指针,它描述了某个文件存在于某一特定的位置,实际文件的位置很可能在其他地方,这有点像 Windows 中的快捷方式。每个软链接都有一个独立的 inode,inode 指向的数据包含了一个字符串,指向链接的目标路径。当目标文件删除时,软链接也不会删除。

和软链接不同,软链接可以区分原始文件和链接,而硬链接无法区分,当硬链接建立后,所有硬链接具有完全相同的地位,硬链接的目录项会指向原始文件的 inode,这和软链接有很大的不同,软链接有自己独立的 inode,这个 inode 中记录了目标文件的路径。硬链接的删除也很不同,对软连接来说被删除不会影响到原始文件,而如果硬链接如果被删除,其对应的原始文件 inode 的引用数就会减一,当 inode 的引用数为 0 时,代表当前没有任何一个硬链接指向该 inode,这时候该 inode 就会被删除。

当用户通过系统调用(传入文件路径)打开一个文件时,内核会为该文件分配一个文件描述符,实际上它是一个起始于 3 的整数(0,1,2 分别被标准输入,标准输出,标准错误占用),当文件打开后,所有对文件的操作都已和文件路径无关了,接下来用户进程需要通过该文件描述符来进行进一步的操作,比如读写。

在 Linux 中有一个万物接文件的设计思想,除了少数部分(网络设备)之外,内核中大部分的导出功能都可以通过 VFS 定义的文件接口访问,例如:

- 字符和块设备

- 进程间通讯管道

- 用于交互式输入输出的终端

- 用于网络协议的套接字

值得一提的是,并不是所有上述对象都能够在 VFS 中以文件的形式显示给用户,例如管道是通过特殊系统调用创建的,它无法在文件目录结构中找到对应的项,但是它实际上是由 VFS 管理的。

VFS 由两个部分组成:文件和文件系统,这些都需要管理和抽象。下图展示了 VFS 各个组件的相互关系,其中主要包括了进程打开文件的管理,下层文件系统的管理,文件 inode 管理,以及文件内存映射地址空间的管理。

因为打开的文件总是分配到系统中一个特定的进程,内核必须在数据结构中存储文件和进程之间的关联。task_struct 包含一个成员,其中保存了所有打开的文件(通过一种迂回方式)。该成员是一个数组,访问时使用文件描述符作为索引。各个数组项包含的对象不仅关联到对应文件的 inode,还包含一个指针,指向用于加速查找操作的目录项缓存的一个成员。

VFS 支持的文件系统类型通过一种特殊的内核对象连接进来,该对象提供了一种读取超级块的方法。除了文件系统的关键信息(块长度、最大文件长度,等等)之外,超级块还包含了读、写、操作 inode 的函数指针。

内核还建立了一个链表,包含所有活动文件系统的超级块实例。之所以使用活动(active)这个术语替代已装载(mounted),是因为在某些环境中,有可能使用一个超级块对应几个装载点(一个文件系统被装载到多个目录)。内核以树形结构来组织装载点,下图给出了 3 种不同的文件系统,全局根目录 / 使用了 Ext2 文件系统,/mnt 为 Reiserfs 文件系统, 而 /mnt/cdrom 使用了 ISO9660 格式,这通常用于光盘。其中 /mnt /mnt/cdrom 被称为装载点,因为这是装载文件系统的位置。将文件系统装载到一个目录时,装载点的内容会被替换为即将装载的文件系统的相对根目录内容。该目录之前的内容将会消失,知道新文件系统写在才会重现(在此期间,旧文件系统的数据不会丢失,只是无法查看)。

超级块结构的一个重要成员是一个列表,包括相关文件系统中所有修改过的 inode(脏inode)。根据该列表很容易标识已经修改过的文件和目录,以便将其回写到存储介质。回写必须经过协调,保证在一定程度上最小化开销,因为这是一个非常费时的操作(硬盘、软盘驱动器及其他介质与系统其余纽件相比,速度很慢)。另一方面,如果写回修改数据的间隔太长也可能有严重后果,因为系统崩溃(或者停电)会导致不能恢复的数据丢失。内核会周期性扫描脏块的列表,并将修改传输到底层硬件。

参考内容

[1]《Linux内核设计与实现》

[2]《Linux系统编程》

[3]《深入理解Linux内核》

[4]《深入Linux内核架构》

[5] https://www.cnblogs.com/hazir/p/linux_kernel_pid.html

[6] http://server.51cto.com/sCollege-198840.htm

[7] https://zhuanlan.zhihu.com/p/68465952

[8] http://www.voidcn.com/article/p-ahfmecnz-brq.html

[9] https://blog.csdn.net/macrossdzh/article/details/5954763

[10] https://baike.baidu.com/item/逻辑地址

[11] https://blog.csdn.net/ywf861029/article/details/6114794

[12] http://liujunming.top/2017/09/03/Linux中匿名页的反向映射/#反向映射的引入

[13] https://blog.csdn.net/sodawaterer/article/details/53456516

[14] http://www.voidcn.com/article/p-odbijlps-bob.html

[15] https://jaminzhang.github.io/network/the-difference-between-unix-domain-socket-and-tcp-ip-socket/

[16] https://www.ilinuxkernel.com/files/Linux.Generic.Block.Layer.pdf

[17] https://blog.csdn.net/YuZhiHui_No1/article/details/50256713

[18] https://blog.51cto.com/guodong810/1176427

[18] https://blog.csdn.net/yang_yulei/article/details/46371975

[19] http://roux.top/2017/10/28/page%20cache%E5%92%8Caddress_space/

[20] https://blog.csdn.net/arkblue/article/details/45796551

[21] https://zhuanlan.zhihu.com/p/73539328

[22] https://blog.csdn.net/renwotao2009/article/details/51979343

[23] https://zhuanlan.zhihu.com/p/70964195

[24] https://www.cnblogs.com/tolimit/p/5435068.html

[25] https://blog.csdn.net/li_wen01/article/details/82659406

[26] https://blog.csdn.net/DLUTBruceZhang/article/details/9919453

[27] https://github.com/caisan/myblog/blob/master/learn-linux-network-namespace.md

[28] https://zh.wikipedia.org/wiki/%E6%98%BE%E5%BC%8F%E6%8B%A5%E5%A1%9E%E9%80%9A%E7%9F%A5

[29] https://www.cnkirito.moe/tcp-talk/

[30] https://juejin.im/post/598ba1d06fb9a03c4d6464ab

[31] https://blog.csdn.net/fw0124/article/details/7452695

[32] https://coolshell.cn/articles/11564.html

[33] https://coolshell.cn/articles/11564.html


  • 本文作者: 贝克街的流浪猫
  • 本文链接:https://www.beikejiedeliulangmao.top/JNI-%E8%B0%83%E8%AF%95%E6%8A%80%E6%9C%AF/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 创作声明: 本文基于上述所有参考内容进行创作,其中可能涉及复制、修改或者转换,图片均来自网络,如有侵权请联系我,我会第一时间进行删除。

linux 文件系统_Linux 虚拟文件系统相关推荐

  1. Linux 文件系统原理 / 虚拟文件系统VFS

    Linux 文件系统原理 / 虚拟文件系统VFS 虚拟文件系统 VFS VFS 定义 VFS 的对象演绎 超级块 super_block 索引节点 inode 目录项 dentry 文件 file 文 ...

  2. linux文件系统_Linux的文件系统简介

    inux操作系统的本质可以说就是文件系统的集合,文件系统既包含文件的数据也包含文件系统的结构.在Linux文件系统中,EXT2文件系统.虚拟文件系统./proc文件系统是三个具有代表性的文件系统./p ...

  3. Linux文件系统概述:硬盘驱动>通用块设备层>文件系统>虚拟文件系统(VFS)

    目录 一.概述 1. 硬盘驱动 2. 通用块设备层 General Block Device Layer 3. 文件系统 4. 虚拟文件系统(VFS) 二.存储介质 闪存(Flash Memory) ...

  4. Linux(一) VFS虚拟文件系统

    一.先了解一下什么是挂载 Linux有自己的一套文件系统,例如Ext2.Ext3,但是外部其他文件系统时,由于各个文件系统都各自有一套的文件管理体系,是无法通过Linux本身访问文件的方式直接访问的, ...

  5. 深入linux内核架构--虚拟文件系统VFS

    [推荐阅读] Linux内核源码分析--内核启动之zImage自解压过程 你应该知道的Linux内核基础及内核编译 深入理解LINUX内核堆栈 [零声教育]vico老师教你怎么学习Linux内核 值得 ...

  6. linux文件系统dentry_Linux 文件系统(一)---虚拟文件系统VFS----超级块、inode、dentry、file...

    一: 什么是文件系统,详见:http://zh.wikipedia.org/zh/%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F 其实一句话就是管理这块文件的机制(组织方式, ...

  7. linux内核之虚拟文件系统

    一.虚拟文件系统概述 虚拟文件系统VFS(也成虚拟文件交换)作为内核子系统,为用户空间程序提供了文件和文件系统相关的统一接口.通过VFS,应用程序可以使用相同接口完成不同介质上不同文件系统的数据读写操 ...

  8. java 虚拟文件系统_虚拟文件系统VFS

    Maven引用坐标: org.tinygroup vfs 0.0.12 一开始,本人抱着对Apache的绝对信任,选择了Apache VFS来进行文件访问的封装,确实,他的API是统一的.优雅的,支持 ...

  9. linux虚拟文件系统浅析

    linux虚拟文件系统浅析 虚拟文件系统(VFS) 在我看来, "虚拟"二字主要有两层含义: 1, 在同一个目录结构中, 可以挂载着若干种不同的文件系统. VFS隐藏了它们的实现细 ...

最新文章

  1. python使用pip安装本地包-python搭建本地pip源,离线安装python模块
  2. [BUUCTF-pwn]——jarvisoj_level4
  3. 全面认识Docker和基本指令
  4. windows10 计算文件的HASH(SHA256\MD5等)
  5. oracle通过DBlink连接mysql
  6. java回忆录—输入输出流详细讲解(入门经典)
  7. Django 配置App特定类的富文本编辑器
  8. MongoDB中对象反序列化的一个小问题
  9. crosses initialization of “XXX”
  10. Exploiting Spatial Structure for Localizing Manipulated Image Regions
  11. 推荐几款好看又好用的开源博客
  12. Json数据的序列化与反序列化的三种常用方法介绍
  13. mixly红外遥控问题在线等
  14. 开源鸿蒙南向嵌入学习笔记——NAPI框架学习(一)
  15. MySQL之导出整个及单个表数据
  16. 分钱、用人和交替,看《大明王朝1566》
  17. 全基因组尺度的增强子--靶基因映射图谱解码非编码突变
  18. 【亲测有效】:genymotion输入中文
  19. 【BUUCTF】MISC 秘密文件
  20. jmeter线程说明_Jmeter-常用线程组设置及场景运行时间计算

热门文章

  1. 每个程序员都必须知道的8种数据结构
  2. 阿里内部禁用Executors创建线程池,为什么?
  3. 进击的 Java ,云原生时代的蜕变
  4. 2019年最新10份开源Java精选资料
  5. mysql 5.1默认缓存_mysql的innodb数据库引擎详解
  6. oracle的正则表达式(regular expression)简单介绍
  7. yolov5改进VariFocalNet
  8. python opencv 投影变换 黑边
  9. pyinstaller 'utf-8' codec can't decode byte 0xce in position 123: invalid continuation byte
  10. Mish激活函数,ReLU的继任者