ext4文件系统与jbd2

哈喽,我是子牙老师,一个手写过操作系统、编程语言、Java虚拟机、docker、Ubuntu系统,玩透Windows内核、Linux内核的…硬核男人

这周想把课程《实战Linux内核》四期关于ext文件系统的部分结掉,本来想着把磁盘分区结构MBR与GPT搞透、再将ext、ext2、ext3、ext4涉及到的分区结构、块组、日志、直接块间接块寻址、extent搞明白,就可以轻松看懂ext4文件系统源码了,看的时候才发现,里面大量journal相关代码
在这里插入图片描述

journal是什么呢?是ext4的日志模块jbd2相关代码。ext4文件系统对目录文件的所有操作,为了防止突发情况导致的元数据不一致,都会封装成jbd2的事务,所以如果你想彻底看懂ext4的源码,必须先将jbd2玩明白
在这里插入图片描述

按照ChatGPT说的学习路径,课程《实战Linux内核》四期已经完成了1、2,现在把3搞明白,再去看ext4源码把4搞明白,ext4文件系统,你就能轻松看懂了
在这里插入图片描述
在这里插入图片描述

这里打个小广告,如果你想真正学会Linux内核,学习我的课程,一定没错!教Linux内核的课程本就不多,以实战的方式讲Linux内核的,仅我一人!彻底学会Linux内核的三个标准:1、能够搭建出单步调试Linux内核环境;2、能够编写驱动在Linux内核中实战;3、能够编写Linux内核模块扩展Linux内核功能,我的课程中全部教!

接下来开始整jbd2,enjoy

为什么要封装成事务

可能很多人不理解,ext4文件系统为什么要将所有操作封装成事务?为什么封装成事务就能保证元数据一致?元数据是什么?

先解释什么是元数据,你通过stat命令查看一个目录看到的信息,就是目录的元信息
在这里插入图片描述

在Linux内核层面,对应的就是ext4_inode、ext4_dir_entry_2
在这里插入图片描述

看看inode=2的信息,数据块是block 730。目录的数据块中存储的是什么?子目录的ext4_dir_entry_2
在这里插入图片描述

接下来说说ext4为什么要把所有操作封装成事务,你知道ext4文件系统创建一个目录要做哪些事情,你自然而言就懂了。就以mkdir为例,让你知道ext4创建一个目录的完整过程

这是ext4文件系统结构,比如在fs目录中创建目录ziya
在这里插入图片描述

创建目录ziya时,第一步就是去申请inode number,去哪申请?inode位图。一个block是1024B,每个位映射一个inode number,1024*8=8172,即一个块组最多可以申请8172个inode number。
在这里插入图片描述

如果申请到了inode,就要将对应的位改为1,比如块组0的inode位图位于block 85,需要将该block读出来,把对应的位改为1,然后写入,这是第一次写盘
在这里插入图片描述

申请到了inode number,就需要创建inode节点,完成初始化,然后落盘,这是第二次写盘
在这里插入图片描述

创建目录ziya时,会自动写入两个dentry:【.】与【…】,需要一个block作为数据盘。就得去读空闲块位图,block bitmap位于block 82,读出来,找到空闲位,改为1,写入,这是第三次写盘

还有将创建的目录ziya的信息写入父目录fs的数据块中,更新父目录fs的inode信息,父目录fs的数据块是block 730,读出来,写入,这是第四次写盘

父目录fs的inode=2,每个struct inode占128B,可以算出,父目录的inode信息在block 88上,读出来,更新数据,写盘,这是第五次写盘。更新哪些信息呢?比如
在这里插入图片描述

ext4文件系统的超级块所在block,也有可能发生数据变动,就涉及到第六次写盘
在这里插入图片描述

创建一个目录,要经历这么多次写盘,如果在某一步,停电了,比如在第二次写篇后停电了,后面的四次写篇都还没做,会发送怎样的结果?是不是就浪费了一个inode?

为了避免发生这样的事,ext4的解决方案是引入日志,即jbd2,将一次操作的所有写盘行为封装成一次事务,写入日志区域。Linux内核中的jbd2进程,会在合适的时机执行日志中的事务
在这里插入图片描述

合适的时机有哪些呢?
在这里插入图片描述

接下来就拿mkdir ziya生成的日志进行分析,看jbd2是怎么玩的

拿jbd2日志数据
开始实战!创建一个盘fs.img,打上ext4文件系统,挂载到fs目录中,进入fs目录,创建目录ziya
在这里插入图片描述

执行了上述操作,来看下事务情况,两条事务数据
在这里插入图片描述

mount会产生事务日志,匪夷所思吧。想不想知道mount产生的日志长啥样?等下带你看

接下来执行mkdir ziya,再看日志情况,多了两条日志
在这里插入图片描述

接下来咱们来分析jbd2产生的日志数据

分析jbd2日志数据

默认情况,jbd2只能使用1M空间,一个block是1024B,jbd2用了1024个block,1M空间是这样用的,结构长这样
在这里插入图片描述

日志超级块,固定使用inode=8,来看看它的信息
在这里插入图片描述

日志超级块的数据块是从8274到9297。我们把它所有日志dump出来进行分析
在这里插入图片描述
在这里插入图片描述

日志分层两段,第一段是mount时产生的,第二段是mkdir时产生的

block 1是执行mount时生成的Descriptor日志信息,block 3是执行mount时生成的Commit信息,那block 2是什么呢?从图中可以猜出,是要写盘的数据块,这个数据块是哪个block的呢?block 88的,如果你不信,可以来论证一下,先看看block 2的内容
在这里插入图片描述

再将block 88 dump出来,看下内容
在这里插入图片描述
在这里插入图片描述

是不是一毛一样。block 88是什么内容呢?inode数据区
在这里插入图片描述

mount时会读ext4文件系统的super block信息,这些信息就存在inode数据区中的第一个block中

再来看第二段,descriptor信息在block 4中,commit信息在block 12中,block 5、6、7、8、9、10、11,,7个block,是哪些block呢?这个信息ChatGPT没解析出来,自己来猜测解析吧
在这里插入图片描述

里面有六个数字:0x55、0x59、0x52、0xe8、0xda,转成十进制
在这里插入图片描述

85是inode位图,89是inode表,82是block位图,都是我们前面讲的创建目录要操作的盘,232、218是什么,就不知道了,找不到任何数据跟这两个数字关联

来看看block 5对应的是不是block 85,还真是,inode位图
在这里插入图片描述

我最开始猜测block 6是block 86,发现不是,然后猜测是block 89,发现也不是
在这里插入图片描述

最后我通过全盘搜索,发现它是block 3的内容。block 3的内容是什么呢?块组信息!想想也有道理,块组如果坏了,有再多信息也没用啊
在这里插入图片描述

block 7的信息是不是block 89呢?看下,发现是的!inode表
在这里插入图片描述

block 8的信息一看就是位图,就是block 82的内容,block位图
在这里插入图片描述

block 9的信息呢?有【.】与【…】,很明显目录ziya的数据区
在这里插入图片描述

ziya的数据区对应的是哪个block呢?
在这里插入图片描述

block 10呢?对应的inode 88,inode数据区,前面提过,创建目录ziya,需要修改父目录fs的inode信息
在这里插入图片描述

那block 11呢?父目录fs的数据区呗。数据区在哪个block上?
在这里插入图片描述

还真是!
在这里插入图片描述

至此,jbd2你已全然知晓!把jbd2讲到这个程度的,全网只有我,不信你可以去百度、Google,或者问任何AI

jbd2的1M空间结构可以优化一下了
在这里插入图片描述

这就是我对技术钻研的态度!也是我做课程的态度!我做的所有课程,都是奔着让你能真正学会去的,技术实力摆在这,我能通过实战让你真正看到!让你真正理解透!

如果你对上面的内容感兴趣,想看我之前的文章及我的奋斗历程。白手起家程序员的职场心得,欢迎看我【个人简介】详细了解。

若有收获,就点个赞吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值