范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

深入剖析虚拟文件系统(VFS)

  1.前言
  Linux采用Virtual Filesystem(VFS)的概念,通过内核在物理存储介质上的文件系统和用户之间建立起一个虚拟文件系统的软件抽象层,使得Linux能够支持目前绝大多数的文件系统,不论它是windows、unix还是其他一些系统的文件系统,都可以挂载在Linux上供用户使用。
  VFS,Virtual File System虚拟文件系统,也称为虚拟文件系统开关(Virtual Filesystem Switch),就是采用标准的Linux系统调用读写位于不同物理介质上的不同文件系统,即为各类文件系统提供了一个统一的操作界面和应用编程接口,VFS是一个内核软件层。
  VFS是一个可以让open、read、write等系统调用不用关心底层的存储介质和文件系统类型就可以工作的抽象层:
  2.VFS结构
  这里以Ext4文件系统示例
  VFS中包含着向物理文件系统转换的一系列数据结构,如VFS超级块(Super Block)、VFS的Inode、各种操作函数的转换入口等。Linux中VFS依靠四个主要的数据结构来描述其结构信息,分别为超级块、索引结点、目录项和文件对象,这些数据结构大都会与磁盘上的对应上。
  VFS对每种类型的对象都定义了一组必须实现的操作。这些类型的每一个对象都包含了一个指向函数表的指针。函数表列出了实际上实现特定对象的操作函数。
  超级块(Super Block):超级块对象表示一个文件系统。它存储一个已安装的文件系统的控制信息,包括文件系统名称(比如Ext2)、文件系统的大小和状态、块设备的引用和元数据信息(比如空闲列表等等)。超级块与磁盘上文件系统的超级块对应。
  所有超级块对象都以双向循环链表的形式链接在一起,对象的自旋锁(sb_lock)保护链表免受多处理器系统上的同时访问。
  索引结点(Inode):索引结点对象存储文件的相关元数据信息,例如:文件大小、设备标识符、用户标识符、用户组标识符等等。Inode分为两种:一种是VFSInode,一种是具体文件系统的Inode。前者在内存中,后者在磁盘中。所以每次其实是将磁盘中的Inode调进填充内存中的Inode,这样才算是使用了磁盘文件Inode。当创建一个文件的时候,就给文件分配了一个Inode。一个Inode只对应一个实际文件,一个文件也会只有一个Inode(Unix/Linux系统中目录也是一种文件,打开目录实际上就是打开目录文件。目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码)。
  从文件的角度来看,目录就是一个特殊的文件
  目录项(Dentry):引入目录项对象的概念主要是出于方便查找文件的目的。不同于前面的两个对象,目录项对象只存在于内存中,实际对应的是磁盘的目录innode对象。VFS在查找的时候,根据一层一层的目录项找到对应的每个目录项的Inode,那么沿着目录项进行操作就可以找到最终的文件。
  文件对象(File):文件对象描述的是进程已经打开的文件。因为一个文件可以被多个进程打开,所以一个文件可以存在多个文件对象,但多个文件对象其对应的索引节点和目录项对象肯定是唯一的
  2.1 SuperBlock
  SuperBlock表示特定加载的文件系统,用于描述和维护文件系统的状态,由VFS定义,但里面的数据根据具体的文件系统填充。每个SuperBlock代表了一个具体的磁盘分区,里面包含了当前磁盘分区的信息,如文件系统类型、剩余空间等。SuperBlock的一个重要成员是链表s_list,包含所有修改过的INode,使用该链表很容易区分出来哪个文件被修改过,并配合内核线程将数据写回磁盘。SuperBlock的另一个重要成员是s_op,定义了针对其INode的所有操作方法,例如标记、释放索引节点等一系列操作。// https://elixir.bootlin.com/linux/v6.0/source/include/linux/fs.h#L1451 结构体已删减
  structsuper_block{
  structlist_heads_list; // 指向链表的指针
  dev_ts_dev; // 设备标识符
  unsignedlongs_blocksize; // 以字节为单位的块大小
  loff_ts_maxbytes; // 文件大小上限
  structfile_system_type*s_type; // 文件系统类型
  conststructsuper_operations*s_op; // SuperBlock 操作函数,write_inode、put_inode 等
  conststructdquot_operations*dq_op; // 磁盘限额函数
  structdentry*s_root; // 根目录
  }
  2.2 DEntry 和 INode
  Linux文件系统会为每个文件都分配两个数据结构,目录项(DEntry, Directory Entry)和索引节点(INode, Index Node)。
  DEntry用来保存文件路径和INode之间的映射,从而支持在文件系统中移动。DEntry由VFS维护,所有文件系统共享,不和具体的进程关联。dentry对象从根目录"/"开始,每个dentry对象都会持有自己的子目录和文件,这样就形成了文件树。举例来说,如果要访问**"/home/ccs/a.txt"文件并对它操作,系统会解析文件路径,首先从"/"根目录的dentry对象开始访问,然后找到"home/"目录,其次是"ccs/",最后找到"a.txt"**的dentry结构体,该结构体里面d_inode字段就对应着该文件。// https://elixir.bootlin.com/linux/v6.0/source/include/linux/dcache.h#L81 结构体已删减
  structdentry{
  structdentry*d_parent; // 父目录
  structqstrd_name; // 文件名称
  structinode*d_inode; // 关联的 inode
  structlist_headd_child; // 父目录中的子目录和文件
  structlist_headd_subdirs; // 当前目录中的子目录和文件
  }
  每一个dentry对象都持有一个对应的inode对象,表示Linux中一个具体的目录项或文件。INode包含管理文件系统中的对象所需的所有元数据,以及可以在该文件对象上执行的操作。// https://elixir.bootlin.com/linux/v6.0/source/include/linux/fs.h#L593 结构体已删减
  structinode{
  umode_ti_mode; // 文件权限及类型
  kuid_ti_uid; // user id
  kgid_ti_gid; // group id
  conststructinode_operations*i_op; // inode 操作函数,如 create,mkdir,lookup,rename 等
  structsuper_block*i_sb; // 所属的 SuperBlock
  loff_ti_size; // 文件大小
  structtimespeci_atime; // 文件最后访问时间
  structtimespeci_mtime; // 文件最后修改时间
  structtimespeci_ctime; // 文件元数据最后修改时间(包括文件名称)
  conststructfile_operations*i_fop; // 文件操作函数,open、write 等
  void*i_private; // 文件系统的私有数据
  }
  虚拟文件系统维护了一个 DEntry Cache缓存,用来保存最近使用的DEntry,加速查询操作。当调用open函数打开一个文件时,内核会第一时间根据文件路径到DEntry Cache里面寻找相应的DEntry,找到了就直接构造一个file对象并返回。如果该文件不在缓存中,那么VFS会根据找到的最近目录一级一级地向下加载,直到找到相应的文件。期间VFS会缓存所有被加载生成的dentry。
  INode存储的数据存放在磁盘上,由具体的文件系统进行组织,当需要访问一个INode时,会由文件系统从磁盘上加载相应的数据并构造INode。一个INode可能被多个DEntry所关联,即相当于为某一文件创建了多个文件路径(通常是为文件建立硬连接)。
  对于inode结构而言,可能有三种主要情况:
  存在内存中,未关联到任何文件,也不处于活动使用状态;
  存在内存中,正在由一个或多个进程使用,正在由一个或多个进程使用,通常表示一个文件。两个计数器(i_count和i_nlink)的值都必须大于0。文件内容和inode元数据都与底层块设备上的信息相同。也就是表示从上一次与介质同步依赖,该inode没有改变过;
  处于活动使用状态。其数据内容已经改变,与存储介质上的内容不同。这种状态的inode被称作脏的。
  2.3 fd 与 file
  每个进程都持有一个fd数组,数组里面存放的是指向file结构体的指针,同一进程的不同fd可以指向同一个file对象;
  file是内核中的数据结构,表示一个被进程打开的文件,和进程相关联。当应用程序调用open函数的时候,VFS就会创建相应的file对象。它会保存打开文件的状态,例如文件权限、路径、偏移量等等。// https://elixir.bootlin.com/linux/v6.0/source/include/linux/fs.h#L940 结构体已删减
  structfile{
  structpathf_path;
  structinode*f_inode;
  conststructfile_operations*f_op;
  unsignedintf_flags;
  fmode_tf_mode;
  loff_tf_pos;
  structfown_structf_owner;
  }
  // https://elixir.bootlin.com/linux/v6.0/source/include/linux/path.h#L8
  structpath{
  structvfsmount*mnt;
  structdentry*dentry;
  }
  3. 抽象层VFS到实现层文件系统3.1挂载
  VFS可以管理各种文件系统,那么VFS和文件系统怎么关联的呢?给用户如何展示的呢?通过挂载。
  如下图所示,该系统根文件系统是Ext3文件系统,而在其/mnt目录下面又分别挂载了Ext4文件系统和XFS文件系统。最后形成了一个由多个文件系统组成的文件系统树。
  挂载是在用户态发起的命令,也就是我们使用的mount命令,该命令执行的时候需要指定文件系统的类型(这里假设是Ext2)和文件系统数据的位置(也就是device)。通过这些关键信息,VFS就可以完成Ext2文件系统的初始化,并将其关联到当前已经存在的文件系统当中,也就是建立起上面所示的文件系统树。
  挂载的过程中,最重要的数据结构就是vfsmount,vfsmount代表的是一个挂载点。其次再是dentry和inode,这两个都是对文件的表示,且都会缓存在哈希表中以提高查找的效率。
  其中inode是对磁盘上文件的唯一表示,其中包含文件的元数据(管理数据)和文件数据等内容,但不含文件名称。而dentry则是为了Linux内核中查找文件方便虚拟出来的一个数据结构,其中包含文件名称、子目录(如果存在的话)和关联的inode等信息。
  dentry结构体最为关键,其维护了内核中的文件目录树。其中里面比较重要的几个结构体分别是d_name、d_hash和d_subdirs。其中d_name代表一个路径节点的名称(文件夹名称)、d_hash则用于构建哈希表,d_subdirs则是下级目录(或文件)的列表。这样,通过dentry就可以形成一个非常复杂的目录树。
  3.2文件处理流程
  文件处理流程包括两步:我们在访问一个文件之前首先要打开它(open)文件访问,然后进行文件的读写操作(read或者write)。
  我们知道,在用户态打开一个文件返回的是一个文件描述符,其实也就是一个整数值;同时,访问文件也是通过这个文件描述符进行的。那么操作系统是怎么通过这个整数值实现不同类型文件系统的访问呢?不同文件系统的差异其实就是inode中初始化的函数指针的差异。
  在Linux操作系统中,文件的打开必须要与进程(或者线程)关联,也就是说一个打开的文件必须隶属于某个进程。
  在linux内核当中一个进程通过task_struct结构体描述,而打开的文件则用file结构体描述,打开文件的过程也就是对file结构体的初始化的过程。在打开文件的过程中会将inode部分关键信息填充到file中,特别是文件操作的函数指针。在task_struct中保存着一个file类型的数组,而用户态的文件描述符其实就是数组的下标。这样通过文件描述符就可以很容易到找到file,然后通过其中的函数指针访问数据。
  我们以Ext2文件系统的写数据为例来看看文件处理流程和各个层级之间的关系,如下图。
  在调用用户态的写数据接口的时候,需要传入文件描述符。内核根据文件描述符找到file,然后调用函数接口(file->f_op->write)文件磁盘数据。其中file结构体的f_op指针就是在打开文件的时候通过inode初始化的。
  4.总结
  虚拟文件系统是操作系统中非常重要的一层抽象,其主要作用在于让上层的软件,能够用统一的方式,与底层不同的文件系统沟通。在操作系统与底层的各类文件系统之间,虚拟文件系统提供了标准的操作接口,让操作系统能够很快地支持新的文件系统。也因为 VFS 的支持,众多不同的实际文件系统才能在 Linux 中共存,跨文件系统的操作才能实现。
  附上一张各组件交互图吧
  参考资料:
  《深入理解Linux内核》第三版
  《Linux 虚拟文件系统》

女人夏天不要错过这道菜,鲜美营养足,随手一炒,好吃还不长肉导语夏至后,少吃猪肉多吃它,低脂高蛋白,正当季,别不懂吃。大家好我是傻姐美食,生活中唯有美食和美景不可辜负。最近几天看新闻,好多地方都是高温湿热的天气,因为气温较高,人体的消化能力白酒圈公认好喝的大牌平价酒,再喝不起趁早戒酒飞天茅台(酱香)329953度平替款台仙福酱(酱香)33853度酱香浓郁回味悠长口感跟飞天有一拼2五粮液(浓香)101052度平替款小水井(浓香)180元52度500ml细腻雅致,让夏天过得清爽又舒适吧炎炎夏日,气温开始上升。少不了要用到风扇,给大家推荐这款荣芝的空气循环扇。RONGEO荣芝空气循环扇可以3D循环送风,上下左右自动摇头,全方位无死角送风。搭配空调使用可以更快地降温2022年夏天交易签约汇总伍德被交易到独行侠格兰特联手利拉德1掘金将执行820万美元的球员选项杰马考格林和一个受保护的2027年首轮签(前五保护)交易到雷霆,换回2022NBA选秀大会30号签和20232024年两个次轮签。2火箭克里斯蒂安夏天,孩子们都爱戏水捞鱼,很容易出现溺水的情况,如何预防?北京儿童医院急诊内科主任王荃真实的溺水是无声快速的。当发现孩子在水中保持目光呆滞看向前方,头上扬嘴微张的姿势时,家长就要警惕孩子可能溺水了。预防溺水,家长要注意两点。第一,不要让孩期待!孙兴慜有望加盟皇马五大下家出炉皇马领跑曼城利物浦在列北京时间6月25日,孙兴慜五大下家出炉,知名英媒太阳报列出孙兴慜的潜在下家,分别是西甲皇马法甲巴黎德甲拜仁英超利物浦英超曼城。从太阳报给出的情况来看,在这场孙兴慜争夺战当中,皇马处吃饭时,常喝2两白酒的人,身体会变成什么样,建议喝酒的人看看喝酒能使人的心情变得愉悦!只不过就目前的白酒市场来说,我们担心的不是有没有酒喝,而是考虑如何在鱼龙混杂的白酒市场当中,挑选到一款适合自己的酒才是重中之重,毕竟白酒挑选不好,会对身体男人年过40再喝白酒,要注意什么?建议牢记4点,早知好处多人到中年不得已,酒精杯中泡枸杞!这句话真是生动表达出了一位中年男人的现状。现代人生活压力大,而男人作为一家人的顶梁柱,不能轻言放弃,更不能啰里叭嗦,只能派头苦干,苦了累了难受了,大医疗煤炭军工白酒以及新能源等板块分析医疗中证医疗现在还是典型的箱体震荡走势,不过这个位置震荡的周期比较长,对该板块还是挺有利的。接下来就看价格能不能顺利突破箱体了,若能突破并企稳,行情可能就来了。白酒中证白酒经过近两中超小将复刻卢卡库机智跑位骗走多名防守,外援借此打进精彩进球中超第六轮比赛,天津津门虎靠着外援罗萨的中超处子球,以10击败梅州客家,取得两连胜梅州客家则遭遇赛季首场失利。此役,天津津门虎共完成13脚射门4脚射正打进1球。同时,津门虎全场送出为何伊朗石油4美元一桶,我国油价频繁暴涨,两种方法可平抑油价众所周知,近几个月来,国内油价一路高升,这也让有车一族有些吃不消。按照石油价格管理办法规定,国内油价要与国际油价挂钩,每10个工作日要对价格进行计算,之后按照新价格的进行调整。我国
惊蛰前后,不管再忙,别忘记喝2茶食4物,润燥营养好处多都说春雷响,万物长,随着惊蛰前后雷雨增多,天气变暖,万物都开始生长。但需要注意的是,惊蛰期间的气温仍不稳定,北方地区温差较大,大家迫不及待换上春装的时候也别小看倒春寒的影响。这段时没有篮网的命,却得了篮网的病首先需要指出的是这里的篮网指的是交易前,有杜兰特和凯里欧文的那支篮网。那时候的篮网,进攻围绕两名超级巨星,其他人得到空位机会投篮,防守则主要靠渡边等替补,两名巨星对防守的投入看两位帐篷和花朵同时盛开露营季回归带动周末经济升温新民晚报讯(记者杨硕)周末帐篷被提前订满平台搜索热度上涨450线上商户新增70春暖花开助推周末经济升温,在成都广州深圳等城市,一顶顶帐篷和花朵同时盛开,展现着各地的消费活力。新一年全国人大代表齐鲁制药集团总裁李燕建议强化孕产妇抑郁症等心理健康问题的常规筛查金融界3月6日消息,2023年是推进中国式现代化新征程的启航之年,如何开好局起好步,两会将传递重要信号。今年全国人大代表齐鲁制药集团总裁李燕带来了关于强化孕产妇抑郁症防治工作的建议900万,加盟湖人!在詹姆斯身边提升一点,你的身价就会突飞猛进湖人应该庆幸,他们主场战胜了来势汹汹的勇士。面对着五连胜,同时迎回了库里的勇士,湖人在没有詹姆斯和拉塞尔这两大持球核心的情况下,硬是撑到了最后。说实话,如果不是库里最后手感没有续上夏花三个惊喜瞬间上头,网友百看不厌夏花完结后,各平台的热度,依然非常高。尤其是剧中的删减版,再一次登上了收视高峰,电视剧逆袭第一。女主角的主动,成为了观众们的精神支柱,同时言承旭的高颜值,让观众无法释怀,太帅了。生恭喜!失孤原型郭刚堂儿子郭振将本月大婚,孙海洋已确认参加3月6日,据亲爱的原型孙海洋在与好友聚餐直播时透露,3月19日要到山东聊城参加郭刚堂儿子郭振的婚礼,消息一出让不少网友为郭刚堂和郭振感到开心。说起孙海洋和郭刚堂都是万千寻亲路中的代常友科技IPO老板带领亲友奔小康,还向神秘人借千万现金买房车刘文叶家族吃肉,亲友们喝汤?作者刘钦文编辑丨武丽娟来源野马财经因地制宜,因材施教。其目的都是要将优势发挥到最大用处。不同的地区因地理位置不同,历史环境不同,优势产业也有所不同。在江坐着火车游中国专列旅游节启动放送300万专列惠民券长沙晚报掌上长沙3月6日讯(实习生曾昭萍通讯员李健)为响应文化和旅游部号召,促进文旅市场快速复苏振兴,助力恢复旅游消费活力,同时更好地满足中老年春季旅游消费需求,各地出台多种优惠政客场不敌广厦北控遭遇三连败京报体育记者王洋3月6日晚,北京控股男篮在2022至2023赛季CBA常规赛第31轮中,以90比110不敌浙江广厦,遭遇三连败。晋级季后赛希望渺茫。上轮,北控客场以87比101不敌沙特阿拉伯提高了4月份的石油价格欧洲央行近期面临高核心通胀01沙特阿拉伯提高了4月份的石油价格沙特阿拉伯上调了向亚洲和欧洲出口的大部分原油价格,暗示其认为亚洲和欧洲的石油需求将会上升。虽然石油期货今年略有走弱,但随着中国经济在解除冠状病毒