linux:Ext系列文件系统
1.磁盘相关硬件磁盘计算机中唯一一个机械硬件具有容量大价格便宜但处理速度慢等特点但是如今在普通家用计算机中已经被固态硬盘取代只在有数据存储需求的大企业中因其相对于固态硬盘的极低价格仍在使用服务器将多个磁盘集成装载在一起的具有cpu网卡等硬件的一个装置没有显示器键鼠机柜由多个服务器集成在一起的装置机房将多个机柜集成管理放置在一起的一个专门的房间2.磁盘的物理结构与存储2.1.物理结构磁头图中类似指针的东西就是磁头通过磁头和盘片的有磁区域进行法拉第电磁感应将盘片信息转变为二进制电信号然后读取该电信号即可盘片图中圆圈形状的盘子多片它上面通过设置不同区域为NS磁极的任意一极用NS表示01信息从而可以保存二进制数据信息主轴负责带动盘片进行旋转的装置方便磁头的读写操作磁头只需要左右移动即可2.2.存储名词解释1盘面一个盘片具有两面且两面都是存储着信息的2.磁道盘面的数据是环形分布的所以一个环就是一个磁道3.扇区每个磁道都可以均匀分成n份每一份都是扇形的区域所以又叫扇区CHS定位方式信息都是存储在盘片上的而盘片的数据区定位可以分成三个步骤1.定位使用的磁头(header)因为一个磁头对应一个盘面我们定位磁头就是确定数据在哪个盘面上编号从0开始2.定位磁道(cylinder)我们将磁头左右摆动从而移动到数据具体处于的磁道上编号从0开始3.定位扇区(sector)主轴马达转动让盘片集体转动直到数据所在扇区被磁头指向编号从1开始磁盘逻辑抽象与新定位方式就像我们的磁带可以从一卷打开成一条一样我们的磁盘亦可以看成是一维数组此时我们就可以把每一个扇区的位置都用数组下标寻找到而使用索引查找数据位置的逻辑抽象地址叫LBA地址疑问如何从LBA地址转换为CHS地址信息由于磁头磁道都是从0开始编号扇区都是从1开始编号有如下计算公式header LBA/盘面总扇区数cylinder (LBA%盘面总扇区数)/单磁道扇区数sector (LBA%盘面总扇区数)%单磁道扇区数同理从CHS转换为LBA地址的公式为header*盘面总扇区数sector*单磁道扇区数sector磁盘真正的展开方式以柱面为单位展开的三维数组柱面所有盘面的同一对应磁道构成的圆柱面展开磁道由扇区组成的一维数组展开柱面由n个盘面的磁道组成的二维数组展开磁盘n个柱面组成的三维数组而CHS定位法的三个元素值就是该三维数组的下标c:柱面h磁头s扇区。三者分别是三维数组的xyz下标然后根据我们c/c的理解可以将三维数组变为一维数组去维护补充操作系统将数据写入磁盘的过程io基本大小是4KBdiradd和data都是寄存器dir用于记录读写方向用01做区分add用于记录读写的数据lba地址data用于传输数据进入磁盘空间将传输总线的数据一点点的传输给磁盘存储空间类似水龙头3.文件系统3.1块硬盘是块设备因为操作系统读取硬盘的数据的时候不是一个一个扇区读取的而是一次性读取多个扇区这种读取叫块读取。最常见的块是由八个扇区组成的而操作系统也是根据块号进行磁盘读取的下面我们看看LBA地址和块号的转换块号*8 块的LBA起始地址块号*8偏移量0~7 扇区具体LBA地址3.2磁盘分区我们都知道电脑中有c盘d盘等盘这其实不代表我们有多个物理磁盘因为所有的c盘d盘等盘都是一块物理磁盘的分区磁盘分区之后八个扇区合为一个块若干块合并为一个组从此我们管理磁盘的对象就是一个组了3.2.1块组管理其实就是将多个块的空间合并为一个组的空间形成一个自管理系统进行数据管理文件 文件内容 文件属性内容存储在数据块中属性存储在inode中superBlock文件系统的总目录GDT是块组描述符表一个结构体数组存储的是块组描述符结构体描述块组自身的信息BlockBitmap数据块位图用于记录特定编号数据块是否被占用inodeBitmapinode位图用于记录特定编号inode是否被启用inodeTable保存该组所有文件属性存放本组所有的inode结构体Data Blocks数据块真正存放文件内容的地方详细介绍1.BlockBitmap与inodeBitmap他们都是位图位图一般使用int数组或字符数组来实现位图中数据的每一个bit位都表示一个对应编号的数据块或inode编号。位为0表示该位置未被占用位为1表示该位置被占用2.一般而言一个文件占用一个inode一个文件可能占用0个或多个datablock疑问inode和data是分开存放的我们如何通过inode找到该文件内容的数据块的位置inode中有一个i_block数组数组内容就是该文件存储的数据块的块号i_block的可存储元素个数为15.疑问i_block的可存储个数只有15个而一个数据块只有4kb这是否意味着文件大小上限就是4*15kb其实i_block不是所有位置都存储直接指向一个存储文件内容的数据块的指针只有前12个位置是后面存储的分别是一级二级三级间接块索引表指针我们以一级间接块为例他存储的指针指向的也是一个数据块但是该数据块存储的不是具体文件内容而是指向负责存储具体文件内容的数据块的指针同理二级间接块指向的数据块存储的就是指向一级间接块索引表的指针3.inodetable内部结构在磁盘格式化阶段就已经将所有inode结构体创建好了只是大部分处于未启用状态而我们新建文件的时候就会从对应分组中申请一个inode使用4.GDT存放在块组0中但是会备份到其他若干个块组中GDT中存储的块组描述符结构体中存储的主要是块组各分区的起始块号以及块的使用情况等5.superblock负责管理整个分区的文件系统信息和GDT一样会有多个备份在不同块组中这样即使某一个块组的superblock坏了这个分区仍然可以使用6.疑问inode编号是分区有效的但是每个块中的inodebitmap的表示位都是从0开始的这是否矛盾结论不矛盾局部inode编号inode位图表示位inodetable索引号编号从0开始全局inode编号局部inode编号块组inode数*块组编号1编号从1开始由于每个块组中的inode数量是固定的所以每个块组中的全局inode编号不是从0开始的而是要继承前面块组的inode编号接着往大编号使用局部inode编号都要加上固定的偏移量才能变为全局inode编号。1是为了让从0开始编号的局部inode编号也变为从1开始从而与全局统一3.2.2分区中文件操作过程描述1.新建文件从inode位图中找一个编号对应位为0的未启用inode将文件属性写入inode结构体中若文件内容大小不为0在datablock位图中找数据块编号位为0的未启用数据块找到后在inode的i_block映射数组中存储该数据块编号建立映射关系然后存储文件内容进数据块2.删除文件不需要清空数据块中存储的内容和inode结构体中的内容根据inode编号在inode位图中查找该文件使用信息若该文件确实在使用中进入inode结构体找到i_block映射数组中该文件映射的所有数据块号在datablock位图中将对应编号位置为0在datablock位图修改完成后将inode位图的inode编号位也置为0疑问为什么我们有数据恢复操作是有什么魔法吗其实这是因为计算机的数据删除都是状态删除仅仅将对应数据存在状态设置为0数据恢复操作就可以根据需要恢复文件的inode编号找到对应文件设置inode位图为启用然后同理恢复文件数据块状态需要注意的是如果是内容覆盖删除无法进行数据恢复所以当文件误删时停止一切编辑操作避免数据覆盖导致数据内容事实删除3.2.3目录与文件名疑问1其实文件名并不存储在文件的inode结构体中那么他存储在哪里答存储在目录文件的数据块中目录文件和普通文件在存储上没有区别他也有inodedatablock以及对应位图等而目录文件的inode存储的是他的文件属性datablock存储的是目录文件内容他的内容就是目录内文件名和文件inode的映射数组。所以我们根据文件名打开文件实际上是调用了目录文件的datablock中的映射数组信息依据inode查找并打开文件新建文件的本质用户给文件名系统给inode然后存储inode和文件名的映射关系到目录文件的datablock中所以新建文件需要有目录文件的w权限x权限决定用户是否能打开目录r权限决定用户是否能查看目录内容疑问2打开目录中的文件的前提是什么/home/lhc/linux/code/test.c结论带上完整路径溯源到根目录假设我们要根据test.c文件名打开test.c文件那么我们就需要从他的目录code中找到inode和文件名的映射也就是说我们需要code的inode打开code文件的datablock可是code也是一个处于linux目录下的文件同理接下来我们需要知道linux的inode-lhc的inode-home的inode递归过程最终会查找到根目录的inode而根目录inode是确定的递归可以回溯了这个过程叫做路径解析疑问3如果说我们每次都要逐层递归查看路径那么linux中tree命令是怎么做到查看全部目录及文件信息的答因为linux会在路径解析过程中逐渐形成目录树并进行路径缓存实现方式通过dentry结构体的连接构建目录树对于已经访问过的文件可以通过根目录的dentry结构体逐层搜索而不用一直逐层解析1dentry结构体逻辑关系每个dentry都表示一个目录从根目录的dentry开始不断往下拓展从属关系所以做路径解析的时候都是直接从根目录的dentry开始往下进行目录比对如果最后比对成功解析完成最后没比对到就创建新目录的dentry结构体进行链接2解析过程3.2.4磁盘分区过程与挂载磁盘分区过程第一步划分好各分区区域第二步对每个分区进行格式化使其在文件系统规则中第三步对分区进行挂载挂载将对应分区放置在指定目录下接入系统的目录树结构使得该分区可以被系统访问注意1.挂载点挂载点就是指定挂载的目录该点具有阻断功能可以确保目录成为挂载点之后存储空间完全独立eg根目录被挂载与c盘/home被挂载与d盘虽然我们说根目录下的所有文件都是用c盘但是这适用于后续没有成为挂载点的目录当后续目录成为挂载点后从他开始的后续目录/home/....都是使用d盘空间2.windows与linux的设计区别在linux中通常根目录和用户目录都是被挂载到不同分区上的这是为了防止用户数据空间溢出后影响到根目录的系统基本操作在windows中为了使用的统一性他将系统目录和用户目录都放置在c盘中当c盘被填满数据后由于系统没有空间创建临时文件可能出现系统崩溃的情况3.inode无法跨区那么我们怎么知道给定inode属于哪个分区我们先通过路径解析找到inode对应文件所处的具体路径然后从尾部开始反向逐步匹配成为挂载点的目录最先匹配到挂载点分区的就是当前inode文件所处的分区4.软硬链接4.1操作方式软链接示范硬链接示范软链接使用ln -s 目标文件 链接名硬链接使用ln 目标文件 链接名4.2区别与原理软硬链接创建文件情况软连接的text_soft文件属于一个新的文件他的inode和text.c不一样硬链接的text_hard文件和text.c是同一个文件只是名字不一样软链接软链接文件的内容保存的是链接文件的字符串绝对路径就像windows的快捷方式一样同时软连接也让用户不用关心软件版本是否更新因为软连接会在应用更新的时候快速更改链接对象为更新后的对象硬链接本质是在当前目录的datablock中加入硬链接文件名和连接对象inode的映射关系所以他的第一个作用就是重命名第二个作用备份指定文件他可以通过硬链接指定文件来实现文件备份如果我们删除原文件实际上他是没有被删了唯一的变动是该文件的硬链接引用计数--我们仍然可以通过inode找到该文件在权限字符串后面跟着的就是硬链接数的引用计数注意1.对于目录来说可能会有三种常见硬链接第一个是自己第二个是 . ,第三个是..这也是为什么我们cd .就是进入当前目录在子目录中cd ..可以进入父目录4.3使用规范我们可以对任意目录/文件使用软连接但是不能对目录使用硬链接这是为了防止出现路径回环目标找到ext_len文件。假设我们将lin_len设置为home的硬链接那么查询到lin_len就会跳转到home然后接着往下查找找到lin_len又会跳转到home从而进入路径回环死循环查找疑问那为什么系统又可以设置./..这些目录硬链接因为系统可以在实现的底层对这些硬链接进行特殊处理在路径查找的时候直接跳过从而避免路径回环