关系经济人类预测化学自然
中准网
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

底层原理一层层剥开文件系统的面纱,彻底理解Linux文件系统

11月23日 虎狼旗投稿
  概述
  提到文件系统,Linux的老江湖们对这个概念当然不会陌生,然而刚接触Linux的新手们就会被文件系统这个概念弄得晕头转向,恰好我当年正好属于后者。
  从windows下转到Linux的童鞋听到最多的应该是fat32和ntfs(在windows2000之后所出现的一种新型的日志文件系统),那个年代经常听到说我要把C盘格式化成ntfs格式,D盘格式化成fat32格式。
  一到Linux下,很多入门Linux的书籍中当牵扯到文件系统这个术语时,二话不说,不管三七二十一就给出了下面这个图,然后逐一解释一下每个目录是拿来干啥的、里面会放什么类型的文件就完事儿了,弄得初学者经常丈二和尚摸不着头脑。
  本文的目的就是和大家分享一下我当初是如何学习Linux的文件系统的,也算是一个老油条的一些心得吧。
  文件系统的主语是文件,那么文件系统的意思就是用于管理文件的(管理)系统,在大多数操作系统教材里,文件是数据的集合这个基本点是一致的,而这些数据最终都是存储在存储介质里,如硬盘、光盘、U盘等。
  另一方面,用户在管理数据时也是文件为基本单位,他们所关心的问题是:1。我的文件在什么地方放着?2。我如何将数据存入某个文件?3。如何从文件里将数据读出来?4。不再需要的文件怎么将其删除?
  简而言之,文件系统就是一套用于定义文件的命名和组织数据的规范,其根本目的是便对文件进行查询和存取。虚拟文件系统VFS
  在Linux早期设计阶段,文件系统与内核代码是整合在一起的,这样做的缺点是显而易见的。假如,我的系统只能识别ext3格式的文件系统,我的U盘是fat32格式,那么很不幸的是我的U盘将不会被我的系统所识别,
  为了支持不同种类的文件系统,Linux采用了在Unix系统中已经广泛采用的设计思想,通过虚拟文件系统VFS来屏蔽下层各种不同类型文件系统的实现细节和差异。
  其实VFS最早是由Sun公司提出的,其基本思想是将各种文件系统的公共部分抽取出来,形成一个抽象层。对用户的应用程序而言,VFS提供了文件系统的系统调用接口。而对具体的文件系统来说,VFS通过一系列统一的外部接口屏蔽了实现细节,使得对文件的操作不再关心下层文件系统的类型,更不用关心具体的存储介质,这一切都是透明的。ext2文件系统
  虚拟文件系统VFS是对各种文件系统的一个抽象层,抽取其共性,以便对外提供统一管理接口,便于内核对不同种类的文件系统进行管理。那么首先我们得看一下对于一个具体的文件系统,我们该关注重点在哪里。
  对于存储设备(以硬盘为例)上的数据,可分为两部分:用户数据:存储用户实际数据的部分;管理数据:用于管理这些数据的部分,这部分我们通常叫它元数据(metadata)。
  我们今天要讨论的就是这些元数据。这里有个概念首先需要明确一下:块设备。所谓块设备就是以块为基本读写单位的设备,支持缓冲和随机访问。每个文件系统提供的mk2fs。xx工具都支持在构建文件系统时由用户指定块大小,当然用户不指定时会有一个缺省值。
  我们知道一般硬盘的每个扇区512字节,而多个相邻的若干扇区就构成了一个簇,从文件系统的角度看这个簇对应的就是我们这里所说块。用户从上层下发的数据首先被缓存在块设备的缓存里,当写满一个块时数据才会被发给硬盘驱动程序将数据最终写到存储介质上。如果想将设备缓存中数据立即写到存储介质上可以通过sync命令来完成。
  块越大存储性能越好,但浪费比较严重;块越小空间利用率较高,但性能相对较低。如果你不是专业的骨灰级玩儿家,在存储设备上构建文件系统时,块大小就用默认值。通过命令tune2fsldevsda1可以查看该存储设备上文件系统所使用的块大小:〔rootlocalhost〕
  该命令已经暴露了文件系统的很多信息,接下我们将详细分析它们。
  下图是我的虚拟机的情况,三块IDE的硬盘。容量分别是:
  hda:37580963840(102410241024)35GBhdb:8589934592(102410241024)8GBhdd:8589934592(102410241024)8GB
  如果这是三块实际的物理硬盘的话,厂家所标称的容量就分别是37。5GB、8。5GB和8。5GB。可能有些童鞋觉得虚拟机有点假,那么我就来看看实际硬盘到底是个啥样子。
  主角1:西部数据500GSATA接口CentOS5。5
  实际容量:500107862016B465。7GB
  主角2:希捷160GSCSI接口CentOS5。5
  实际容量:160041885696B149GB
  大家可以看到,VMware公司的水平还是相当不错的,虚拟硬盘和物理硬盘根本看不出差别,毕竟属于云平台基础架构支撑者的风云人物嘛。
  相关视频推荐
  3个linux内核的秘密,让你彻底搞懂文件系统
  剖析Linux内核虚拟文件系统(VFS)架构
  学习地址:CCLinux服务器开发后台架构师【零声教育】学习视频教程腾讯课堂
  需要CCLinux服务器架构师学习资料加qun812855908(资料包括CC,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCPIP,协程,DPDK,ffmpeg,大厂面试题等)
  以硬盘devhdd1为例,它是我新增的一块新盘,格式化成ext2后,根目录下只有一个lostfound目录,让我们来看一下它的布局情况,以此来开始我们的文件系统之旅。
  对于使用了ext2文件系统的分区来说,有一个叫superblock的结构,superblock的大小为1024字节,其实ext3的superblock也是1024字节。下面的小程序可以证明这一点:includestdio。hincludelinuxext2fs。hincludelinuxext3fs。hintmain(intargc,charargv){printf(sizeofofext2superblockd,sizeof(structext2superblock));printf(sizeofofext3superblockd,sizeof(structext3superblock));return0;}【运行结果】sizeofofext2superblock1024sizeofofext3superblock1024
  硬盘的第一个字节是从0开始编号,所以第一个字节是byte0,以此类推。devhdd1分区头部的1024个字节(从byte0byte1023)都用0填充,因为devhdd1不是主引导盘。superblock是从byte1024开始,占1024B存储空间。我们用dd命令把superblock的信息提取出来:ddifdevhdd1of。hdd1sbbs1024skip1count1
  上述命令将从devhdd1分区的byte1024处开始,提取1024个字节的数据存储到当前目录下的hdd1sb文件里,该文件里就存储了我们superblock的所有信息,上面的程序稍加改造,我们就可以以更直观的方式看到superblock的输出了如下:includestdio。hincludesystypes。hincludesysstat。hincludefcntl。hincludeunistd。hincludestring。hincludelinuxext2fs。hincludelinuxext3fs。hintmain(intargc,charargv){printf(sizeofofext2superblockd,sizeof(structext2superblock));printf(sizeofofext3superblockd,sizeof(structext3superblock));charbuf〔1024〕{0};intfd1;structext2superblockhdd1memset(hdd1sb,0,1024);if(1(fdopen(。hdd1sb,ORDONLY,0777))){printf(openfileerror!);return1;}if(1read(fd,buf,1024)){printf(readerror!);close(fd);return1;}memcpy((char)hdd1sb,buf,1024);printf(inodecount:ld,hdd1sb。sinodescount);printf(blockcount:ld,hdd1sb。sblockscount);printf(Reservedblockscount:ld,hdd1sb。srblockscount);printf(Freeblockscount:ld,hdd1sb。sfreeblockscount);printf(Freeinodescount:ld,hdd1sb。sfreeinodescount);printf(FirstDataBlock:ld,hdd1sb。sfirstdatablock);printf(Blocksize:ld,1(hdd1sb。slogblocksize10));printf(Fragmentsize:ld,1(hdd1sb。slogfragsize10));printf(Blockspergroup:ld,hdd1sb。sblockspergroup);printf(Fragmentspergroup:ld,hdd1sb。sfragspergroup);printf(Inodespergroup:ld,hdd1sb。sinodespergroup);printf(Magicsignature:0xx,hdd1sb。smagic);printf(sizeofinodestructure:d,hdd1sb。sinodesize);close(fd);return0;}【运行结果】inodecount:1048576blockcount:2097065Reservedblockscount:104853Freeblockscount:2059546Freeinodescount:1048565FirstDataBlock:0Blocksize:4096Fragmentsize:4096Blockspergroup:32768Fragmentspergroup:32768Inodespergroup:16384Magicsignature:0xef53sizeofinodestructure:128
  可以看出,superblock的作用就是记录文件系统的类型、block大小、block总数、inode大小、inode总数、group的总数等信息。
  对于ext2ext3文件系统来说数字签名Magicsignature都是0xef53,如果不是那么它一定不是ext2ext3文件系统。这里我们可以看到,我们的devhdd1确实是ext2文件系统类型。hdd1中一共包含1048576个inode节点(inode编号从1开始),每个inode节点大小为128字节,所有inode消耗的存储空间是1048576128128MB;总共包含2097065个block,每个block大小为4096字节,每32768个block组成一个group,所以一共有20970653276863。99,即64个group(group编号从0开始,即Group0Group63)。所以整个devhdd1被划分成了64个group,详情如下:
  用命令tune2fs可以验证我们之前的分析:
  再通过命令dumpe2fsdevhdd1的输出,可以得到我们关注如下部分:
  接下来以Group0为例,主superblock在Group0的block0里,根据前面的分析,我们可以画出主superblock在block0中的位置如下:
  因为superblock是如此之重要,一旦它出错你的整个系统就玩儿完了,所以文件系统中会存在磁盘的多个不同位置会存在主superblock的备份副本,一旦系统出问题后还可以通过备份的superblock对文件系统进行修复。
  第一版ext2文件系统的实现里,每个Group里都存在一份superblock的副本,然而这样做的负面效果也是相当明显,那就是严重降低了磁盘的空间利用率。所以在后续ext2的实现代码中,选择用于备份superblock的Group组号的原则是3的N次方、5的N次方、7的N次方其中N0,1,2,3。根据这个公式我们来计算一下devhdd1中备份有supeblock的Group号:
  也就是说Group1、3、5、7、9、25、27、49里都保存有superblock的拷贝,如下:
  用block号分别除以32768就得到了备份superblock的Group号,和我们在上面看到的结果一致。我们来看一下devhdd1中Group和block的关系:
  从上图中我们可以清晰地看出在使用了ext2文件系统的分区上,包含有主superblock的Group、备份superblock的Group以及没有备份superblock的Group的布局情况。存储了superblock的Group中有一个组描述符(Groupdescriptors)紧跟在superblock所在的block后面,占一个block大小;同时还有个ReservedGDT跟在组描述符的后面。
  ReservedGDT的存在主要是支持ext2文件系统的resize功能,它有自己的inode和datablock,这样一来如果文件系统动态增大,ReservedGDT就正好可以腾出一部分空间让Groupdescriptor向下扩展。
  接下来我们来认识一下superblock,inode,block,group,groupdescriptor,blockbitmap,inodetable这些家伙。superblock
  这个东西确实很重要,前面我们已经见识过。为此,文件系统还特意精挑细选的找了N多后备Group,在这些Group中都存有superblock的副本,你就知道它有多重要了。
  说白了,superblock的作用就是记录文件系统的类型、block大小、block总数、inode大小、inode总数、group的总数等等。groupdescriptors
  千万不要以为这就是一个组描述符,看到descriptor后面加了个s就知道这是N多描述符的集合。确实,这是文件系统中所有group的描述符所构成的一个数组,它的结构定义在includelinuxext2fs。h中:Structureofablocksgroupdescriptorstructext2groupdesc{le32group中blockbitmap所在的第一个block号le32group中inodebitmap所在的第一个block号le32group中inodestable所在的第一个block号le16group中空闲的block总数le16group中空闲的inode总数le16目录数le16le32bgreserved〔3〕;};
  下面的程序可以帮助了解一下devhdd1中所有group的descriptor的详情:defineBLEN32一个structext2groupdesc{}占固定32字节intmain(intargc,charargv){charbuf〔BLEN〕{0};inti0,fd1;structext2memset(gd,0,BLEN);if(1(fdopen(argv〔1〕,ORDONLY,0777))){printf(openfileerror!);return1;}while(i64){因为我已经知道了devhdd1中只有64个groupif(1read(fd,buf,BLEN)){printf(readerror!);close(fd);return1;}memcpy((char)gd,buf,BLEN);printf(Groupd:,i);printf(Blocksbitmapblockld,gd。bgblockbitmap);printf(Inodesbitmapblockld,gd。bginodebitmap);printf(Inodestableblockld,gd。bginodetable);printf(Freeblockscountd,gd。bgfreeblockscount);printf(Freeinodescountd,gd。bgfreeinodescount);printf(Directoriescountd,gd。bguseddirscount);memset(buf,0,BLEN);i;}close(fd);return0;}
  运行结果和dumpe2fsdevhdd1的输出对比如下:
  其中,文件gp0decp是由命令ddifdevhdd1of。gp0decpbs4096skip1count1生成。每个groupdescriptor里记录了该group中的inodetable的起始block号,因为inodetable有可能会占用连续的多个空闲的block、inode数等等。blockbitmap:
  在文件系统中每个对象都有一个对应的inode节点(这句话有些不太准确,因为符号链接和它的目标文件共用一个inode),里存储了一个对象(文件或目录)的信息有权限、所占字节数、创建时间、修改时间、链接数、属主ID、组ID,如果是文件的话还会包含文件内容占用的block总数以及block号。inode是从1编号,这一点不同于block。
  需要格外注意。另外,devhdd1是新挂载的硬盘,格式化成ext2后并没有任何数据,只有一个lostfound目录。接下来我们用命令ddifdevhdd1of。gp0bs4096count32768将Group0里的所有数据提取出来。
  前面已经了解了Group0的一些基本信息如下:Group0:(Blocks032767)Primarysuperblockat0,Groupdescriptorsat11ReservedGDTblocksat2512Blockbitmapat513(513),Inodebitmapat514(514)Inodetableat5151026(515)31739freeblocks,16374freeinodes,1directories包含一个目录Freeblocks:10281031,103332767一共有31739个空闲blockFreeinodes:1116384一共有16374个空闲inode
  一个blockbitmap占用一个block大小,而blockbitmap中每个bit表示一个对应block的占用情况,0表示对应的block为空,为1表示相应的block中存有数据。在devhdd1中,一个group里最多只能包含8409632768个block,这一点我们已经清楚了。接下来我们来看一下Group0的blockbitmap,如下:
  发现blockbitmap的前128字节和第129字节的低4位都为1,说明发现Group0中前128841028个block,即block0block1027都已被使用了。第129字节的高4位为0,表示block1028block1031四个block是空闲的;第130字节的最低位是1,说明block1032被占用了;从block1033block32767的blockbitmap都是0,所以这些block都是空闲的,和上表输出的结果一致。inodebitmap
  和blockbitmap类似,innodebitmap的每个比特表示相应的inode是否被使用。Group0的inodebitmap如下:
  devhdd1里inode总数为1048576,要被均分到64个Group里,所以每个Group中都包含了16384个inode。要表示每个Group中16384个inode,inodebitmap总共需要使用2048(163848)字节。inodebitmap本身就占据了一个block,所以它只用到了该block中的前2048个字节,剩下的2048字节都被填充成1,如上图所示。
  我们可以看到Group0中的inodebitmap前两个字节分别是ff和03,说明Group0里的前11个inode已经被使用了。其中前10个inode被ext2预留起来,第11个inode就是lostfound目录,如下:
  inodetable
  那么每个Group中的所有inode到底存放在哪里呢?答案就是inodetable。它是每个Group中所有inode的聚合地。
  因为一个inode占128字节,所以每个Group里的所有inode共占163841282097152字节,总共消耗了512个block。Group的groupdescriptor里记录了inodetable的所占block的起始号,所以就可以唯一确定每个Group里inodetable所在的block的起始号和结束号了。inode的结构如下:
  这里我们主要关注的其中的数据block指针部分。前12个block指针直接指向了存有数据的block号;第13个block指针所指向的block中存储的并不是数据而是由其他block号,这些block号所对应的block里存储的才是真正的数据,即所谓的两级block指针;第14个block为三级block指针;第15个block为四级block指针。最后效果图如下:
  一个block为4096字节,每个块指针4字节,所以一个block里最多可以容纳409641024个block指针,我们可以计算出一个inode最大能表示的单个文件的最大容量如下:
  直接block指针(字节)
  两级block指针(字节)
  三级block指针(字节)
  四级block指针(字节)
  单个文件的最大容量(字节)
  12409
  409644096
  4096244096
  4096344096
  4TB
  所以,我们可以得出不同block大小,对单个文件最大容量的影响。假设block大小为X字节,则:
  如下表所示:
  block大小(字节)
  单个文件容量(字节)
  1024hr17247240192字节(16GB)
  2048hr275415826432字节(256GB)
  4096hr4402345672704字节(4TB)
  最后来一张全家福:
投诉 评论 转载

商贸零售双11倒计时商贸零售:双11倒计时预售是主要战场品牌力大比拼一触即发投资要点大促时间:天猫预售时间有所推迟,其余平台大促时间变化不大。2022年天猫双11预售……打响2022年大屏市场第一炮!TCL98英寸电视销量占比超5纵观整个2021年的智屏市场,屏幕大尺寸化毫无疑问成为了最流行的趋势。85英寸以上的超大屏电视已经成为不少消费者的首选,其市场占比也在持续增加。根据奥维云网(AVC)公布……丁俊晖公开回应假球事件这与学院无关,也与我无关!近日,对于沸沸扬扬的梁文博假球事件,丁俊晖在采访中正式公开回应,这也让球迷们放下担忧和悬着的心,因为,丁俊晖并不知道,也未参与,而且丁俊晖也明确表示:目前,他也不想参与其中。……长津湖杨根思和冰雕连为何至死不退?看看他们的位置就明白了杨根思和冰雕连究竟为什么打到死也不撤退?要知道,他们本有机会活下来。是上级命令他们必须战死吗?显然不是。我军作战虽然不怕死,但从来都反对没有意义的牺牲,形势不利条件下,一……超好玩德国科幻小说,帮助全球无数家长引导孩子播下科技的种子!科幻是最好的激发孩子想象力的领域。以往我们也向大家推荐过不少顶级的儿童科幻作品,孩子们纷纷表示无敌好看,有的书上架快一年了还不断的有家长回购。这套同样无敌好看又爆笑的德国……5。32亿创纪录!4人续约新进展!两新星或签肥约,塔图姆冲击在约基奇签下超级顶薪的带动下,今夏休赛期的自由市场,可以说迎来了大爆发般的球员签约和续约。当然,现实的情况是,在今夏的休赛期当中,包括比尔、拉文和利拉德在内,确实有不少球……底层原理一层层剥开文件系统的面纱,彻底理解Linux文件系统概述提到文件系统,Linux的老江湖们对这个概念当然不会陌生,然而刚接触Linux的新手们就会被文件系统这个概念弄得晕头转向,恰好我当年正好属于后者。从window……涟水县外国语学校和实验幼儿园蓓蕾幼儿园联合举办幼小衔接活动幼小衔接我们在行动为深入推进幼小科学衔接,进一步贯彻落实《教育部关于大力推进幼儿园与小学科学衔接的指导意见》等文件精神,6月13日,涟水县外国语学校和涟水县实验幼儿园、蓓……润肺第一补,和鸡蛋绝配!这样做养心健脾远离咳嗽白露时节秋燥起,饮食上适合吃一些滋阴润燥的食材,百合就是一个非常好的选择。百合色白入肺,不仅能润肺养阴,对很多秋季常见的小毛病也有缓解作用。秋季润肺第一补百合……电脑桌面杂乱无章?不美观?这三款神器帮你解决!你的电脑桌面是不是这样子的?(图片来源于网络)又或者是这样?(图片来源于网络)杂乱的文件与图标,让人眼花缭乱,还影响壁纸的观感。一个有序且简洁的桌面可以……FacebookShops脸书商店开通设置教学ampampaAppify在移动电商行业已经有足够的经验沉淀来发挥有助于跨境电商发展的关键功能。从App定制开发到App应用营销策略,再到品牌全域整合,通过Appify小编的介绍,你将了解移……今年流行的阔腿裤真显瘦,学习这3个搭配小心机,穿上人人都夸你如今走在大街上,你会发现90的小姐姐穿的都是阔腿裤,和以往流行的紧身裤相比,阔腿裤的好处真的是太多了,不但能够保证舒适感,关键是它遮肉效果也很好。像那些梨型身材小姐姐基本上都对……
多渠道保市场主体中信银行综合金融服务支持实体经济装修公司电话销售技巧电话销售人员必看土地继承纠纷的解决途径有哪些年挣十几万农村创业致富的好项目穷人迈向有钱人的关键八步,我曾经也是这么走过来的下一周(9。139。17)持有这些个股的要小心了(附个股名单中国的传统节日作文字导轨式升降货梯特点定位营销靠谱吗7连阳创7个月最佳战绩,低价股下一个掘金点在哪?荐书解忧杂货店花卉服盆需多长时间
大型沼气设备的防火间距是多少关于孝敬名言适合女人创业的项目个赚钱最给力采矿权行政许可受理书必须办理吗?pushbutton是什么牌子?pushbutton是什么档40岁张萌真会扮嫩,穿红色公主裙甜美又俏皮,网友不像中年女性私人借钱利息多少合法,个人借款没约定利息怎么办?2K屏手机不贵了,12GB256GB仅2399元,这3款低价汤姆索亚历险记读后感作文女性更年期如何饮食推荐这些食物哥哥与父母收养的妹妹解除收养后能否结婚?玻璃水杯刻什么字玻璃水杯子刻字短句

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州