44 ext4 文件系统

发布时间:2024年01月13日

前言

在 linux 中常见的文件系统 有很多, 如下?

基于磁盘的文件系统, ext2, ext3, ext4, xfs, btrfs, jfs, ntfs?
内存文件系统, procfs, sysfs, tmpfs, squashfs, debugfs?
闪存文件系统, ubifs, jffs2, yaffs ?

文件系统这一套体系在 linux 有一层 vfs 抽象, 用户程序不用关心 底层文件系统的具体实现, 用户只用操作 open/read/write/ioctl/close 的相关 系统调用, 这一层系统调用 会操作 vfs 来处理响应的业务?

vfs 会有上面各种文件系统对应的 读写 相关服务, 进而 将操作下沉到 具体的文件系统?

我们这里看一下 ext4 文件系统?

将业务数据存储在磁盘的一个文件系统, 读写数据 最终会提交到磁盘设备?

将数据暂存在内存中物理页,?动态刷出到磁盘?

如何分配inode ?

在创建该文件的时候,?ext4fs 会创建对应的?inode, 并将改?inode?添加到?父级节点

创建?inode 操作来自于,?父级目录的?i_op->create, ext4fs中对应于?ext4_create

这里主要是基于?ext4fs 的?super_block 新建?inode, 初始化?i_no, i_mapping, i_op, i_fop 什么的?

接下来是 查找 group, 分配文件节点,?这里可以看得出来?ext4 文件系统对于?文件数量的限定是一个 逻辑上的限定

接下来是初始化?inode/ext4_inode 的相关其他信息

普通文件的?i_fop 为?ext4_file_operations

另外就是创建了文件之后,?还需要将文件的相关信息?添加到文件夹中记录

这里?ext4_find_dest_de 会找到?父文件夹的数据内容中存放当前文件的地址, 如果有则找到?已有的文件的地址,?如果没有在父文件夹的数据内容末尾 记录当前新增文件的信息

这里?就是设置文件夹中 新增/更新文件元数据的地方

这里记录几个信息项?inode, rec_len, name_len, file_type, name ?

查看 /jerry 的文件夹的内容, buffered_head

0xffff88007dc08630:     29 '\035'       0 '\000'        0 '\000'        0 '\000'        36 '$'  0 '\000'        26 '\032'       1 '\001'
0xffff88007dc08638:     84 'T'  101 'e' 115 's' 116 't' 49 '1'  51 '3'  83 'S'  105 'i'
0xffff88007dc08640:     103 'g' 110 'n' 97 'a'  108 'l' 80 'P'  97 'a'  114 'r' 101 'e'
0xffff88007dc08648:     110 'n' 116 't' 65 'A'  110 'n' 100 'd' 67 'C'  104 'h' 105 'i'
0xffff88007dc08650:     108 'l' 100 'd' 0 '\000'        0 '\000'        30 '\036'       0 '\000'        0 '\000'        0 '\000'
0xffff88007dc08658:     36 '$'  0 '\000'        28 '\034'       1 '\001'        84 'T'  101 'e' 115 's' 116 't'
0xffff88007dc08660:     49 '1'  51 '3'  83 'S'  105 'i' 103 'g' 110 'n' 97 'a'  108 'l'
0xffff88007dc08668:     80 'P'  97 'a'  114 'r' 101 'e' 110 'n' 116 't' 65 'A'  110 'n'
0xffff88007dc08670:     100 'd' 67 'C'  104 'h' 105 'i' 108 'l' 100 'd' 46 '.'  99 'c'
0xffff88007dc08678:     31 '\037'       0 '\000'        0 '\000'        0 '\000'        -120 '\210'     1 '\001'        5 '\005'        1 '\001'
0xffff88007dc08680:     50 '2'  46 '.'  116 't' 120 'x' 116 't' 0 '\000'        0 '\000'        0 '\000'
0xffff88007dc08688:     0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'

# 这里内存中的 0xffff88007dc08678 开始 为 /jerry 目录下面 我们新增的 2.txt 的数据条目 
inode_no 为 0x00 00 00 1f 
rec_len 为 0x01 88
name_len 为 0x05 
file_type 为 0x01 
name 为 2.txt 

/jerry/xx 是在哪里创建的????

这个创建取决于实际的业务,?业务/内核 代码向 ext4fs 中写出具体的数据到具体的文件?

那么执行?该代码的时候 就会创建对应的文件

如何分配存储空间???

存储空间是来自于 pagecache, 然后 具体的数据是来自于 磁盘设备?

??从磁盘读取数据到内存的调试?

如何读写数据 ?

a_ops->write_begin 会获取?maping, pos 对应的物理页,?如果不存在?则向 pagecache 进行申请?

然后?iov_iter_copy_from_user_atomic 的实现是将?用户空间待写出的数据 写出到给定的 物理页,?然后?系统会定时将脏页刷出到磁盘

读取文件的时候?根据 mapping, index 获取磁盘文件块,?加载到?page?

这一部分的内容参见?从磁盘读取数据到内存的调试?

?copy_page_to_iter 即为读取的操作,?将物理页的数据拷贝到?buf 中

如何根据?path?获取到上下文的数据??

上面在?i_op->create 中创建了?inode, 但是并没有提到将?inode 注册到?dir?中或者怎么怎么样?

那么?读取文件的时候怎么关联找到这个 inode 呢??

然后?之后才是走的上面的 i_op->lookup 在父目录的内容中查找?目标文件的条目[ext4_dir_entry_2], 这里可以拿到?i_no, 然后使用?ext4_iget_normal 来获取对应的?inode?的信息, 这里也会缓存一份?dentry 的数据到?dcache

然后?在之后 读取该文件的时候,?lookup_fast 的时候去?dcache_hashtable 中查询对应的?dentry?的信息?

进而拿到?inode, 以及?inode 相关附加信息

进而是根据?inode, 以及上下文,?封装?file?对象

完?
?

文章来源:https://blog.csdn.net/u011039332/article/details/128879061
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。