ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【Linux】Ext系列文件系统(磁盘级文件)

2026/10/2 2:19:37 拓冰建站 浏览量
【Linux】Ext系列文件系统(磁盘级文件) 个人主页道尔柯南❄专栏传送门《C语言》《C》《Linux操作系统》昙花一现却等待了整个白昼蝉鸣一夏却蛰伏了好几个四季。文章目录1-计算机硬件1.1 磁盘1.2 磁盘结构1.3 磁盘的逻辑1.4 CHS LBA地址2-文件系统2.1 块概念2.2 分区概念2.3 inode概念3- ext2文件系统3.1 宏观认识3.2 Block Group3.3 块组内部构成3.3.1 超级块Super Block3.3.2 GDTGroup Descriptor Table3.3.3 块位图Block Bitmap3.3.4 inode位图Inode Bitmap3.3.5 i节点表(Inode Table)3.3.6 Data Block3.4 inode和datablock映射(弱化)3.5 ⽬录与⽂件名3.6 路径解析3.7 路径缓存3.8 挂载分区4-软硬链接4.1 硬链接4.2 软链接4.3 软硬链接对比4.4 软硬链接的用途结尾1-计算机硬件1.1 磁盘机械磁盘是计算机中唯一的一个机械设备它容量大价格便宜1.2 磁盘结构扇区是磁盘存储数据的基本单位512字节块设备如何定位一个扇区呢可以先定位磁头header确定磁头要访问哪一个柱面(磁道)cylinder定位一个扇区(sector)CHS地址定位扇区是从磁盘读出和写入信息的最小单位通常大小为 512 字节。磁头head数每个盘片一般有上下两面分别对应1个磁头共2个磁头磁道track数磁道是从盘片外圈往内圈编号0磁道1磁道…靠近主轴的同心圆用于停靠磁头不存储数据柱面cylinder数磁道构成柱面数量上等同于磁道个数扇区sector数每个磁道都被切分成很多扇形区域每道的扇区数量相同圆盘platter数就是盘片的数量磁盘容量磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数细节传动臂上的磁头是共进退的(这点比较重要后面会说明)柱面cylinder磁头head扇区sector显然可以定位数据了这就是数据定位(寻址)方式之一CHS寻址方式。1.3 磁盘的逻辑磁带上面可以存储数据我们可以把磁带“拉直”形成线性结构。那么磁盘本质上虽然是硬质的但是逻辑上我们可以把磁盘想象成为卷在一起的磁带那么磁盘的逻辑存储结构我们也可以类似于这样每一个扇区就有了一个线性地址(其实就是数组下标)这种地址叫做 LBA柱面是一个逻辑上的概念其实就是每一面上相同半径的磁道逻辑上构成柱面。所以磁盘物理上分了很多面但是在我们看来逻辑上磁盘整体是由“柱面”卷起来的。某一盘面的某一个磁道展开其实就是一维数组整个磁盘所有盘面的同一个磁道即柱面展开就是二维数组。整个磁盘不就是多张二维的扇区数组表(三维数组)所有寻址一个扇区先找到哪一个柱面(Cylinder)在确定柱面内哪一个磁道(其实就是磁头位置Head)在确定扇区Sector所以就有了 CHS 。我们之前学过C/C的数组在我们看来其实全部都是一维数组所以每一个扇区都有一个下标我们叫做 LBA(Logical Block Address) 地址,其实就是线性地址。所以怎么计算得到这个LBA地址呢OS只需要使用LBA就可以了LBA地址转成CHS地址CHS如何转换成为LBA地址。谁做啊磁盘自己来做固件(硬件电路伺服系统)1.4 CHS LBA地址CHS转成LBA:磁头数*每磁道扇区数 单个柱面的扇区总数LBA 柱面号C单个柱面的扇区总数 磁头号H每磁道扇区数 扇区号S - 1即LBA 柱面号C(磁头数每磁道扇区数) 磁头号H*每磁道扇区数 扇区号S - 1扇区号通常是从1开始的而在LBA中地址是从0开始的柱面和磁道都是从0开始编号的总柱面磁道个数扇区总数等信息在磁盘内部会自动维护上层开机的时候会获取到这些参数。LBA转成CHS:柱面号C LBA // (磁头数*每磁道扇区数)【就是单个柱面的扇区总数】磁头号H (LBA % (磁头数*每磁道扇区数)) // 每磁道扇区数扇区号S (LBA % 每磁道扇区数) 1“//”: 表示除取整所以从此往后在磁盘使用者看来根本就不关心CHS地址而是直接使用LBA地址磁盘内部自己转换。所以从现在开始磁盘就是一个元素为扇区的一维数组数组的下标就是每一个扇区的LBA地址。OS使用磁盘就可以用一个数字访问磁盘扇区了。2-文件系统2.1 块概念其实硬盘是典型的块设备操作系统读取硬盘数据的时候其实是不会一个个扇区地读取这样效率太低而是一次性连续读取多个扇区即一次性读取一个块block。硬盘的每个分区是被划分为一个个的块。一个块的大小是由格式化的时候确定的并且不可以更改最常见的是4KB即连续八个扇区组成一个块。块是文件存取的最小单位。注意磁盘就是一个三维数组我们把它看待成为一个一维数组数组下标就是LBA每个元素都是扇区每个扇区都有LBA那么8个扇区一个块每一个块的地址我们也能算出来。知道LBA块号 LBA/8知道块号LAB块号*8n.n是块内第几个扇区2.2 分区概念其实磁盘是可以被分成多个分区partition的以Windows观点来看你可能会有一块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的一种格式化。但是Linux的设备都是以文件形式存在那是怎么分区的呢柱面是分区的最小单位我们可以利用参考柱面号码的方式来进行分区其本质就是设置每个区的起始柱面和结束柱面号码。此时我们可以将硬盘上的柱面分区进行平铺将其想象成一个大的平面。 注意柱面大小一致扇区个位一致那么其实只要知道每个分区的起始和结束柱面号知道每一个柱面多少个扇区那么该分区多大其实和解释LBA是多少也就清楚了。2.3 inode概念之前我们说过文件数据属性我们使用 ls -l 的时候看到的除了看到文件名还能看到文件元数据属性。Linux中任何正常文件都要有自己的属性集合。Linux下内容和属性是分开存储的每行包含7列模式硬链接数文件所有者组大小最后修改时间文件名ls -l读取存储在磁盘上的文件信息然后显示出来其实这个信息除了通过这种方式来读取还有一个stat命令能够看到更多信息到这我们要思考一个问题文件数据都储存在块中那么很显然我们还必须找到一个地方储存文件的元信息属性信息比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode中文译名为索引节点。每一个文件都有对应的inode里面包含了与该文件有关的一些信息。为了能解释清楚inode我们需要是深入了解一下文件系统。 注意Linux下文件的存储是属性和内容分离存储的Linux下保存文件属性的集合叫做inode一个文件一个inodeinode内有一个唯一的标识符叫做inode号所以一个文件的属性inode长什么样子呢/* * Structure of an inode on the disk */structext2_inode{__le16 i_mode;/* File mode */__le16 i_uid;/* Low 16 bits of Owner Uid */__le32 i_size;/* Size in bytes */__le32 i_atime;/* Access time */__le32 i_ctime;/* Creation time */__le32 i_mtime;/* Modification time */__le32 i_dtime;/* Deletion Time */__le16 i_gid;/* Low 16 bits of Group Id */__le16 i_links_count;/* Links count */__le32 i_blocks;/* Blocks count */__le32 i_flags;/* File flags */union{struct{__le32 l_i_reserved1;}linux1;struct{__le32 h_i_translator;}hurd1;struct{__le32 m_i_reserved1;}masix1;}osd1;/* OS dependent 1 */__le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */__le32 i_generation;/* File version (for NFS) */__le32 i_file_acl;/* File ACL */__le32 i_dir_acl;/* Directory ACL */__le32 i_faddr;/* Fragment address */union{struct{__u8 l_i_frag;/* Fragment number */__u8 l_i_fsize;/* Fragment size */__u16 i_pad1;__le16 l_i_uid_high;/* these 2 fields */__le16 l_i_gid_high;/* were reserved2[0] */__u32 l_i_reserved2;}linux2;struct{__u8 h_i_frag;/* Fragment number */__u8 h_i_fsize;/* Fragment size */__le16 h_i_mode_high;__le16 h_i_uid_high;__le16 h_i_gid_high;__le32 h_i_author;}hurd2;struct{__u8 m_i_frag;/* Fragment number */__u8 m_i_fsize;/* Fragment size */__u16 m_pad1;__u32 m_i_reserved2[2];}masix2;}osd2;/* OS dependent 2 */};/* * Constants relative to the data blocks */#defineEXT2_NDIR_BLOCKS12#defineEXT2_IND_BLOCKEXT2_NDIR_BLOCKS#defineEXT2_DIND_BLOCK(EXT2_IND_BLOCK1)#defineEXT2_TIND_BLOCK(EXT2_DIND_BLOCK1)#defineEXT2_N_BLOCKS(EXT2_TIND_BLOCK1)备注EXT2_N_BLOCKS15再次注意文件名属性并未纳入到inode数据结构内部inode的大小一般是128字节或者256我们后面统一128字节任何文件的内容大小可以不同但是属性大小一定是相同的目前为止相信大家还有两个问题我们已经知道硬盘是典型的“块”设备操作系统读取硬盘数据的时候读取的基本单位是”块“。”块“又是硬盘的每个分区下的结构难道”块“是随意的在分区上排布的吗那要怎么找到”块“呢还有就是上面提到的存储文件属性的inode又是如何放置的呢文件系统就是为了组织管理这些的3- ext2文件系统3.1 宏观认识所有的准备⼯作都已经做完是时候认识下⽂件系统了。**我们想要在硬盘上储⽂件必须先把硬盘格式化为某种格式的⽂件系统才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。**在Linux 系统中最常⻅的是 ext2 系列的⽂件系统。其早期版本为 ext2后来⼜发展出 ext3 和 ext4。ext3 和 ext4 虽然对 ext2 进⾏了增强但是其核⼼设计并没有发⽣变化我们仍是以较⽼的 ext2 作为演⽰对象。ext2⽂件系统将整个分区划分成若⼲个同样⼤⼩的块组 (Block Group)如下图所⽰。只要能管理⼀个分区就能管理所有分区也就能管理所有磁盘⽂件。上图中启动块Boot Block/Sector的⼤⼩是确定的为1KB由PC标准规定⽤来存储磁盘分区信息和启动信息任何⽂件系统都不能修改启动块。启动块之后才是ext2⽂件系统的开始。3.2 Block Groupext2⽂件系统会根据分区的⼤⼩划分为数个Block Group。⽽每个Block Group都有着相同的结构组成。3.3 块组内部构成3.3.1 超级块Super Block存放⽂件系统本⾝的结构信息描述整个分区的⽂件系统信息。记录的信息主要有bolck 和 inode的总量未使⽤的block和inode的数量⼀个block和inode的⼤⼩最近⼀次挂载的时间最近⼀次写⼊数据的时间最近⼀次检验磁盘的时间等其他⽂件系统的相关信息。Super Block的信息被破坏可以说整个⽂件系统结构就被破坏了超级块在每个块组的开头都有⼀份拷⻉第⼀个块组必须有后⾯的块组可以没有。 为了保证⽂件系统在磁盘部分扇区出现物理问题的情况下还能正常⼯作就必须保证⽂件系统的super block信息在这种情况下也能正常访问。所以⼀个⽂件系统的super block会在多block group中进⾏备份这些super block区域的数据保持⼀致。3.3.2 GDTGroup Descriptor Table块组描述符表描述块组属性信息整个分区分成多个块组就对应有多少个块组描述符。每个块组描述符存储⼀个块组 的描述信息如在这个块组中从哪⾥开始是inode Table从哪⾥开始是DataBlocks空闲的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有⼀份拷⻉。3.3.3 块位图Block BitmapBlock Bitmap中记录着Data Block中哪个数据块已经被占⽤哪个数据块没有被占⽤3.3.4 inode位图Inode Bitmap每个bit表⽰⼀个inode是否空闲可⽤。3.3.5 i节点表(Inode Table)• 存放⽂件属性 如 ⽂件⼤⼩所有者最近修改时间等• 当前分组所有Inode属性的集合• inode编号以分区为单位整体划分不可跨分区3.3.6 Data Block数据区存放⽂件内容也就是⼀个⼀个的Block。根据不同的⽂件类型有以下⼏种情况• 对于普通⽂件⽂件的数据存储在数据块中。• 对于⽬录该⽬录下的所有⽂件名和⽬录名存储在所在⽬录的数据块中除了⽂件名外ls -l命令看到的其它信息保存在该⽂件的inode中。• Block 号按照分区划分不可跨分区3.4 inode和datablock映射(弱化) 结论• 分区之后的格式化操作就是对分区进⾏分组在每个分组中写⼊SB、GDT、BlockBitmap、Inode Bitmap等管理信息这些管理信息统称: ⽂件系统• 只要知道⽂件的inode号就能在指定分区中确定是哪⼀个分组进⽽在哪⼀个分组确定是哪⼀个inode• 拿到inode⽂件属性和内容就全部都有了下⾯通过touch⼀个新⽂件来看看如何⼯作创建⼀个新⽂件主要有以下4个操作存储属性内核先找到⼀个空闲的i节点这⾥是655524。内核把⽂件信息记录到其中。存储数据该⽂件需要存储在三个磁盘块内核找到了三个空闲块300,500800。将内核缓冲区的第⼀块数据复制到300下⼀块复制到500以此类推。记录分配情况⽂件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表。添加⽂件名到⽬录新的⽂件名abc。linux如何在当前的⽬录中记录这个⽂件内核将⼊⼝655524pyt添加到⽬录⽂件。⽂件名和inode之间的对应关系将⽂件名和⽂件的内容及属性连接起来。3.5 ⽬录与⽂件名问题• 我们访问⽂件都是⽤的⽂件名没⽤过inode号啊• ⽬录是⽂件吗如何理解答案• ⽬录也是⽂件但是磁盘上没有⽬录的概念只有⽂件属性⽂件内容的概念。•⽬录的属性不⽤多说内容保存的是⽂件名和Inode号的映射关系所以访问⽂件必须打开当前⽬录根据⽂件名获得对应的inode号然后进⾏⽂件访问。访问⽂件必须要知道当前⼯作⽬录本质是必须能打开当前⼯作⽬录⽂件查看⽬录⽂件的内容3.6 路径解析问题打开当前⼯作⽬录⽂件查看当前⼯作⽬录⽂件的内容?当前⼯作⽬录不也是⽂件吗我们访问当前⼯作⽬录不也是只知道当前⼯作⽬录的⽂件名吗要访问它不也得知道当前⼯作⽬录的inode吗答案1所以也要打开当前⼯作⽬录的上级⽬录额…上级⽬录不也是⽬录吗不还是上⾯的问题吗答案2所以类似递归需要把路径中所有的⽬录全部解析出⼝是/根⽬录。最终答案3⽽实际上任何⽂件都有路径访问⽬标⽂件⽐如:/home/whb/code/test/test/test.c都要从根⽬录开始依次打开每⼀个⽬录根据⽬录名依次访问每个⽬录下指定的⽬录直到访问到test.c。这个过程叫做Linux路径解析。 注意• 所以我们知道了访问⽂件必须要有⽬录⽂件名路径的原因• 根⽬录固定⽂件名inode号⽆需查找系统开机之后就必须知道可是路径谁提供• 你访问⽂件都是指令/⼯具访问本质是进程访问进程有CWD进程提供路径。• 你open⽂件提供了路径可是最开始的路径从哪⾥来• 所以Linux为什么要有根⽬录, 根⽬录下为什么要有那么多缺省⽬录• 你为什么要有家⽬录你⾃⼰可以新建⽬录•上⾯所有⾏为本质就是在磁盘⽂件系统中新建⽬录⽂件。⽽你新建的任何⽂件都在你或者系统指定的⽬录下新建这不就是天然就有路径了嘛• 系统⽤⼾共同构建Linux路径结构3.7 路径缓存问题1Linux磁盘中存在真正的⽬录吗答案不存在只有⽂件。只保存⽂件属性⽂件内容问题2访问任何⽂件都要从/⽬录开始进⾏路径解析答案原则上是但是这样太慢所以Linux会缓存历史路径结构问题3Linux⽬录的概念怎么产⽣的答案打开的⽂件是⽬录的话由OS⾃⼰在内存中进⾏路径维护Linux中在内核中维护树状路径结构的内核结构体叫做 struct dentry3.8 挂载分区我们已经能够根据inode号在指定分区找⽂件了也已经能根据⽬录⽂件内容找指定的inode了在指定的分区内我们可以为所欲为了。可是问题inode不是不能跨分区吗Linux不是可以有多个分区吗我怎么知道我在哪⼀个分区• 分区写⼊⽂件系统⽆法直接使⽤需要和指定的⽬录关联进⾏挂载才能使⽤。• 所以可以根据访问⽬标⽂件的路径前缀准确判断我在哪⼀个分区。(理解到这个层⾯)4-软硬链接4.1 硬链接我们看到真正找到磁盘上⽂件的并不是⽂件名⽽是inode。其实在linux中可以让多个⽂件名对应于同⼀个inode。• abc和def的链接状态完全相同他们被称为指向⽂件的硬链接。内核记录了这个链接数inode655524 的硬链接数为2。• 我们在删除⽂件时⼲了两件事情1.在⽬录中将对应的记录删除2.将硬连接数-1如果为0则将对应的磁盘释放。4.2 软链接硬链接是通过inode引⽤另外⼀个⽂件软链接是通过名字引⽤另外⼀个⽂件但实际上新的⽂件和被引⽤的⽂件的inode不同软链接是一个独立的文件因为它有独立的inode number应⽤常⻅上可以想象成⼀个快捷⽅式。4.3 软硬链接对比• 软连接是独⽴⽂件• 硬链接只是⽂件名和⽬标⽂件inode的映射关系4.4 软硬链接的用途硬链接• .和… 就是硬链接• ⽂件备份软连接• 类似快捷⽅式结尾uu们本文的内容到这里就全部结束了道尔在这里再次感谢您的阅读道尔柯南C/C Linux 底层探索者 | 一个正在努力学习的技术博主【关注】跟随我一起深耕技术领域见证每一次成长。❤️【点赞】让优质内容被更多人看见让知识传递更有力量。⭐【收藏】把核心知识点存好在需要时随时查、随时用。【评论】分享你的经验或疑问评论区一起交流避坑不要忘记给博主“一键四连”哦“今日目标达成”结语希望对学习Linux相关内容的uu有所帮助不要忘记给博主“一键四连”哦