操作系统-番外-老牌Linux文件系统ext

引言

和标题一样,ext文件系统是一个老牌的Linux的文件系统,是Linux的第一个文件系统。虽然业界将Ext文件系统看成是一个过度用的文件系统,但是现在的Ext4依然有很强的生命力。从ext2-ext3-ext4,文件系统的磁盘布局没有发生太大的变化,从ext2到ext3,主要是增强了可用性、数据完整性、速度、易于迁移等功能;ext3到ext4就不仅仅是功能增强,它修改了某一些重要的数据结构,并且在对大文件的支持上做了更多的优化改进

Ext文件系统磁盘布局
Ext2文件系统磁盘布局

ext文件系统从ext2-ext4磁盘布局并没有太大的改动,如下图
在这里插入图片描述

Block Group

ext文件系统将文件系统分块组管理,在写文件时,尽可能保证文件集中在块组内,减少读取时磁盘旋转的开销。块组的结构如上图,这里要注意,块组0的结构和其他组有点区别,块组0开始位置多了一个固定1024byte用于安装x86引导扇区以及其他信息。

  • super block

    • 定义:块组0的super block是从1024byte偏移量开始的,如果每个group都备份super block,可能造成一些空间浪费,因此提供了sparse_super的设置,如果设置了该sparse_super,那么只有group 0,3、5、7的幂组才会备份super block

    • 可能理论优点抽象,一个简单ext4的例子,是我Linux系统引导分区的例子,首先我们看到并不是所有的组上都有super block的备份,并且备份分别在 0,1,3,5,7,9,25,49,正如上边描述的,开启了sparse_super后,只有0号和3,5,7的幂的组才会备份
      在这里插入图片描述

      下边是7和9组,其他的不列举,如果有兴趣可以用dumpe2fs工具看一下自己的电脑,尽量挑小的分区看,分区太大,数据太多
      在这里插入图片描述

  • GDT(块组描述符表)

    • 定义:记录块组的信息,super block和GDT从组1-组n都是组0的备份,因为super block和GDT是非常重要的信息,为了安全,需要备份

    • GDT的局限,假设一个组描述符占用64byte,块大小为4KB,那么一个组全部存放GDT能存放

      C G D T = 2 27 ÷ 2 6 = 2 21 C_{GDT} = 2^{27} \div 2^{6} = 2^{21} CGDT=227÷26=221

      因此如果块为4KB,那么一个组最多存放GDT为2^{21}个,那么可以表示的最大文件系统大小为组容量乘组数

      C D i s k = 2 27 × 2 21 = 2 48 = 256 P B C_{Disk} = 2^{27} × 2^{21} = 2^{48} = 256PB CDisk=227×221=248=256PB

      通过上面的简单计算,即使第一个组全部用于存放GDT,文件系统大小无法突破256PB的极限。并且,文件系统为了安全,所有组的GDT会随着super block备份,也会消耗很大的文件系统空间,即使设置了sparse_super设置也会

  • block bitmap:记录块组内块的使用情况,同时也限制了块组的块数量,所以块组的最大大小为

    B G _ B _ S I Z E = B _ S I Z E ∗ 8 BG\_B\_SIZE = B\_SIZE * 8 BG_B_SIZE=B_SIZE8

    所以一个4KB块的文件系统,一个组最多可以包含 2 12 ∗ 2 3 = 2 15 = 32768 2^{12}*2^{3} = 2^{15} = 32768 21223=215=32768个块,因此块的大小

    B G _ S I Z E = B _ S I Z E ∗ B G _ B _ S I Z E BG\_SIZE = B\_SIZE * BG\_B\_SIZE BG_SIZE=B_SIZEBG_B_SIZE

    依然假设文件系统为4KB的块,那么一个块组的大小为 2 15 ∗ 2 12 = 2 27 2^{15} * 2^{12} = 2^{27} 215212=227byte,为128MB

  • inode bitmap:记录哪些项在inode table中使用

  • 特殊inode

    inode用途
    0不存在0号inode
    1损坏数据块链表
    2根目录
    3ACL索引
    4ACL数据
    5引导装载程序
    6未删除的目录
    7预留的块组描述符inode
    8日志inode
    9排除在外的inode,用于快照
    10备份inode,用于一些非上游特性
    11第一个非预留的inode,通常是lost + found目录
改进
Meta Block Group(元块组)
  • 定义:改进GDT,上边描述了ext2中GDT的局限,在ext3中引入了Meta Block Group,其固定用一个块来存放GDT,用于记录连续的组组成的一个元块组,GDT不在跟随super block一起备份,而是在自己元块组内备份,分别存放在元块组的1,2号组和最后一个组上。元块组的大小为一个块能存放的组描述数数目

    C M B G = B _ S I Z E ÷ G D T _ S I Z E C_{MBG} = B\_SIZE \div GDT\_SIZE CMBG=B_SIZE÷GDT_SIZE

    假设块组为4KB,组描述符为64byte,那么元块组的大小为 2 12 ÷ 2 6 = 2 6 2^{12} \div 2^6 = 2^6 212÷26=26,为64个

  • 画了一个简单的示意图,凑合着看

    没有使用meta block group的文件系统组分布示意图
    在这里插入图片描述

    使用meta block group的文件系统组分布示意图,
    在这里插入图片描述

Flexible Block Groups
  • 定义:我们知道,机械硬盘每次读取块前要先寻道,相对读取数据,寻道开销是非常高的,而block bitmap、i-node table、i-node table这些数据需要频繁加载,它们分散在各个组上存放就会导致频繁的寻道。为了减少加载block bitmap、i-node table、i-node table时的寻道开销和大文件的连续块分配,ext4引入了Flexible Block Groups,它将一定数量的物理块组连起来组成一个逻辑块组,block bitmap、i-node table、i-node table按顺序存储在逻辑块组的第一个块组上

  • 简单的示意图,注意该图只是一个简单示意图,一个方块并不代表一个块,block bitmip、i-node bitmap依然是一个组一个块,i-node table依顺序占用多个块
    在这里插入图片描述

  • 一个简单的例子,还是以我操作系统为例,先看一下,flexible block group size

    sudo dumpe2fs /dev/sda10 |grep 'Flex'
    

    看到组大小16
    在这里插入图片描述

    然后来看一下组的block bitmap 、i-node bitmap、i-node table分布,可以看到从0-7block bitmap 、i-node bitmap、i-node table都是依次连续的,当然一直到15都是连续的,从第16组开始会变化
    在这里插入图片描述

    再来看一下第16组,是从524288块开始的,它们属于另一个Flexible Block Groups,和上图中flex block group size大小吻合
    在这里插入图片描述

Extent 树
  • 定义:ext2/3时,i-node中指向文件数据块采用直接/间接块地址,如下图,0-11是直接地址,之后的块分为3种,第一种是一级间接地址,第二种是二级,第三种三级,随着间接级数变大,指向的数据块越多,但是这种表示方法有一个缺点,那就是如果数据块连续,依然会每个数据块都存储一个地址,很浪费空间
    在这里插入图片描述

    ext4采用Extent树优化了这种情况,它的核心原理是连续块只存储起始块和连续的块数,每个节点都是以ext4_extent_header(12byte)结构开始,然后如果是内节点,则后边是ext4_extent_idx的项其大小为12byte;如果是叶子节点,则后边是ext4_extent,其大小也是12byte。
    在这里插入图片描述

    • ext4_extent_header结构
      在这里插入图片描述

    • ext4_extent_idx结构
      在这里插入图片描述

    • ext4_extent结构,ee_block该连续块段的第一个块号,ee_len连续块数量,ee_start_hi是该范围段起始指针的高16位,ee_start_lo是该范围段的起始指针低32位
      在这里插入图片描述

目录项
  • 线性(传统)目录,示意图如下,ext4默认是ext4_dir_entry_2,ext4_dir_entry_2和ext4_dir_entry的区别主要是因为文件名不超过255,所以不需要16位存储文件名,因此抽出8位用来存储文件类型,inode 2是系统保留的inode号代表根目录,该图是简单的根目录下的文件目录项示意图,可以看到在块内查找一个文件几乎要遍历目录项数组对比文件名
    在这里插入图片描述

  • Hash树目录,由于传统目录查找文件几乎是遍历查找,出于性能的考虑,ext3引入了文件名hash值的B树来提升查找文件的速度。其结构如下图,树的root通常保存在文件的第一个数据块中,这里有一个地方要注意dx_entry结构中的block号是文件内部的块号,代表是文件的第几个数据块,并非文件系统的块号。
    在这里插入图片描述

    如果dx_root.info.indirect_levels为非零,则htree有两层,根节点并非指向存放ext4_dir_entry_2的叶子节点,而是指向内部节点,其示意图如下,此时根节点中的hash值为其指向内部节点中hash值的最小值
    在这里插入图片描述

jbd2日志
  • jdb2流程简单示意图,写文件时,先写到磁盘缓冲区,然后写到journal(是一个文件系统保留区域,inode为8,大小默认128MB),因为是顺序写,速度很快。当写入完成时,写入一个提交记录,然后刷新磁盘缓冲区。之后文件系统会将journal的提交记录在擦除前写入最终的位置,这里的写就可能会比较慢,因为数据可能需要写到不同块,需要多个寻道开销
    在这里插入图片描述

  • jdb2日志模式

    1. ordered(默认级别):只将文件系统元数据写入journal,当系统崩溃时,不能保证任何一致性状态
    2. journal:所有数据和元数据都会写入到journal,该模式比较慢,但是很安全
    3. writeback:在元数据通过journal写入到磁盘最终位置前,脏数据不能刷新到磁盘
  • 崩溃恢复:当系统崩溃重启时,文件系统利用journal的最近的提交记录重放写过程来恢复数据,journal详细的数据结构参考jdb2

参考
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值