2017-03-08 10:37:55


一、虚拟文件系统VFS

文件系统用于将位于磁盘上的文件按照某种方式组织进内存,并给上层应用程序提供统一的访问接口。Linux支持多种文件系统EXT2/3,NTFS,XFS等,而LInux下支持这些文件系统的方式就是VFS,即虚拟文件系统。虚拟文件系统向上层提供统一的调用接口,向下层请求具体的文件系统。整理架构如图所示。

如上图所描述的,应用程序通过C语言库函数,请求对文件的访问。库函数会调用系统提供的系统调用进入内核,而这里的系统调用不过是一般函数的封装,具体还是要调用VFS提供的调用接口。

虚拟文件系统之所以成为虚拟,源自于其本身并不参与实质性的工作,而是仅仅定义了一组调用接口,像是一个规范一样。这组接口涵盖了几乎所有的文件操作。具体的文件系统不必实现VFS定义的所有操作,只需要根据自己的功能选择性的实现某些操作。

二、虚拟文件系统涉及到的数据结构

一个文件要被访问,自然需要一些数据描述文件的属性,这些信息保存在inode节点中。inode节点主要包含三个部分:文件元数据即访问时间、上次访问日期、引用计数等,具体文件数据和inode操作函数表。从另一个角度,inode其实是磁盘文件在内核中的抽象。对于已经打开的文件,如何恰当的组织才能用最短的时间找到指定文件的inode?Linux通过dentry结构实现这一目的。

1、inode

根据不同文件系统的类型,inode 的实现方式也不同,有些文件系统起初把inode保存在磁盘,后期直接调入到内存如EXT2文件系统;而有些文件系统的inode是在加载文件时动态生成的,如FAT文件系统。VFS中每个文件都有其对应的inode,且只有一个(记住linux依然遵循一切皆文件的道理),所以在inode结构中有很多表示设备文件的字段。在inode中字段记录其引用计数,直到计数值为0时才会被删除,硬链接就是一个很好的例子。inode中包含文件在内存中的映射信息,具体映射由adress_space结构描述。

内存中的inode通过三条链表组织起来,根据inode的状态,分为有效但非活动的inode、使用中但未改变的inode、脏的inode(对应的内容内修改过但是未写入到磁盘)。前面两种保存在全局链表inode_unused、inode_inuse链表中。脏的inode保存在一个特定的超级块的链表中。为了快速查找某个inode,inode还存在于一个散列表中,该散列表是全局表inode_hashtable,散列表的key通过inode编号和超级块地址计算,具体的hash函数在inode的操作函数表中。

2、dentry

dentry 在书上的名称为目录项缓存,其中保存有文件的名称,其本质目的是在具体文件系统路径和inode之间建立一个通道。初次打开一个文件,需要通过底层文件系统和设备驱动和外设交互,没此VFS向底层文件系统发送一个请求,就创建一个dentry保存请求的结果在,这样在下次访问同一个对象时,就不需要访问底层文件系统,直接通过dentry就可以定位具体inode。dentry对象在内存中的组织主要由两种方式:

a) 一个散列表,包含所有的dentry对象。

b) 一个LRU(最近最少使用链表),不在使用的对象不会立即删除,而是设置一个期限,超时后再执行删除。

散列表的哈希函数在dentry对应的操作函数表中,而LRU的表头是全局变量dentry_unused,通过dentry结构中的d_lru连接起来。dentry对象有个计数器d_count,当该计数器到达0时会被置于该链表上,注意,新的向插入链表头,即越往后的dentry,时间就越久,越容易被删除。

2、superblock

该结构式文件系统相关的,每次安装一个文件系统,会有一个对应的超级块结构,当然卸载时,该结构会被删除。每个装载的文件系统对应一个vfsmount结构,用以描述文件系统的装载信息,如装载点的父目录系统、当前文件系统根目录的dentry,还会有指向超级块结构的指针等。

三、进程结构中的文件系统选项

文件系统的存在,无非是让用户去访问文件,而用户如何去发起操作呢?自然是通过进程。各种操作系统的进程访问文件的模式都大同小异,都是先打开进程,然后操作进程。打开进程获取一个局部的文件描述符,windows称之为句柄,该文件描述符只在当前进程内有效。在进程结构task_struct中保存有几个文件系统相关的信息。这里我们只介绍fs_struct和files_struct,对于nsproxy这种命名空间相关,本节不做介绍。

a) files_struct

该结构在进程和打开的文件之间建立连接。在该结构中有个fd_array,是file类型的指针数组,前面提到的文件描述符,其实是该数组的下标。每打开一个文件,就通过数组项纪录在该进程中。而file结构是对应于一个打开的文件,这是相对于进程的,即不同进程打开同一个文件,会有不同的file结构。其中有个比较重要的字段就是f_pos,纪录当前文件偏移,对于读写操作非常重要。还有一个结构f_path,是一个path类型,包含两个指针,分别指向当前文件所述的文件系统结构vfsmount,和文件的目录项结构dentry,通过dentry可以定位具体的inode。而同一文件系统打开的所有文件会通过链表组织起来。

b)fs_struct

该结构记录关于进程本身的一些信息,如当前工作目录的dentry,root的dentry,root文件系统的vfsmount,当前目录的vfsmount等。

下文将结合具体的数据结构内容对各个结构之间的关系进行分析http://www.cnblogs.com/ck1020/p/6544719.html

参考资料:

1、深入Linux内核架构

2、Linux3.10.1内核源码

LInux中的文件系统1的更多相关文章

  1. linux中proc文件系统 -- ldd3读书笔记

    1./proc 文件系统概述 /proc 文件系统是由软件创建,被内核用来向外界报告信息的一个文件系统./proc 下面的每一个文件都和一个内核函数相关联,当文件的被读取时,与之对应的内核函数用于产生 ...

  2. Linux中ext2文件系统的结构

    1.ext2产生的历史 最早的Linux内核是从MINIX系统过渡发展而来的.Linux最早的文件系统就是MINIX文件系统.MINIX文件系统几乎到处都是bug,采用的是16bit偏移量,最大容量为 ...

  3. Linux中文件/文件系统的压缩、打包和备份总结(基于rhel7)

    文件/文件系统的压缩.打包 Linux有哪些压缩工具可供选择 按压缩比:xz>bzip2>gzip,按压缩时长:gzip>bzip2>xz,另外还有zip可以选择. gzip只 ...

  4. 基于redis ae实现 Linux中的文件系统监控机制(inotify)

    (英文部分为转的.代码是个人代码) 1 What's inotify  The inotify API provides a mechanism for monitoring file system ...

  5. 解析Linux中的VFS文件系统机制

    转载:原文地址https://www.ibm.com/developerworks/cn/linux/l-vfs/ 1. 摘要 本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2 ...

  6. 深入理解Linux中内存管理

    前一段时间看了<深入理解Linux内核>对其中的内存管理部分花了不少时间,但是还是有很多问题不是很清楚,最近又花了一些时间复习了一下,在这里记录下自己的理解和对Linux中内存管理的一些看 ...

  7. 【Linux】深入理解Linux中内存管理

    主题:Linux内存管理中的分段和分页技术 回顾一下历史,在早期的计算机中,程序是直接运行在物理内存上的.换句话说,就是程序在运行的过程中访问的都是物理地址. 如果这个系统只运行一个程序,那么只要这个 ...

  8. linux中的分段和分页

    http://blog.csdn.net/hguisu/article/details/6152921 Linux 内存管理 觉得这篇文章写分段和分页机制还是挺清晰的,在此转载一下. 前一段时间看了& ...

  9. Linux磁盘及文件系统(三)Linux文件系统

    一.文件系统的组成 Linux常见的文件系统类型有ReiserFS,ext2,ext3,ext4,vfat,XFS等,文件系统是对一个存储设备上数据和元数据进行组织的机制.他的最终目的是把大量数据有组 ...

随机推荐

  1. 关于love2d教程的更新

    实在抱歉,每周工作六天,一天13小时以上,周日想休息一下,love2d的估计一个月一篇都很难做到了. 三个月后公司的项目应该做完了,那时应该有时间了. love2d估计快发布0.9了,改动应该不是很大 ...

  2. [ADC]Linux ADC驱动

    ADC TI adc user guide: http://processors.wiki.ti.com/index.php/Linux_Core_ADC_Users_Guide 问题: 在tools ...

  3. AtomicReference与volatile的区别

    首先volatile是java中关键字用于修饰变量,AtomicReference是并发包java.util.concurrent.atomic下的类.首先volatile作用,当一个变量被定义为vo ...

  4. golang Time to String

    golang Time to String allenhaozi · 2016-09-02 09:00:00 · 2447 次点击 · 预计阅读时间 1 分钟 · 19分钟之前 开始浏览 这是一个创建 ...

  5. STUN协议简析

    http://blog.csdn.net/mazidao2008/article/details/4934257 ——————————————————————————————————————————— ...

  6. setTranslatesAutoresizingMaskIntoConstraints和setFrame组合使用导致的异常

    在用Ojbect-c开发OSX应用的时候需要用到自定义控件并用代码进行布局,很自然地就使用了setTranslatesAutoresizingMaskIntoConstraints和setFrame组 ...

  7. php接入域账号登陆代码

    php接入域账号登陆代码       //替换本地登录为AD域用户认证//edit by ZhangJin on 2015-05-23 -START-$dn = $user_account.'@fun ...

  8. Linux 串口编程

    今天对应用层串口编程进行了验证.程序来源于以下参考链接,自己进行了一些注释和更改,记录于此. Tony Liu, 2016-6-17, Shenzhen 参考链接 https://www.ibm.co ...

  9. Swift AVFoundation 二维码扫描和生成

    项目最终不须要支持iOS6了(泪崩),在二维码扫描这一块,可以全然的放弃ZXing库,改用系统的AVFoundation了,拿swift写了个Demo,效果例如以下: github地址:点这里 有关A ...

  10. Android实现时间轴

    昨天群里有讨论时间轴的项目,没有接触过,以为非常吊,研究之后才知道表面都是忽悠人的,使用listview就能实现了,也没有什么新奇的东西 废话少说,直接上图 图片和文字都能够私人订制 没什么好说的,直 ...