一、btrfs文件系统介绍
1. 我们现在所使用的文件系统通过df命令查看可以看到分别挂载两个目录,分别为/media/XX 和/mpf/XX,这两个分别是子卷和父卷,/media/XX作为子卷,也有普通目录属性,同时是实际存储数据的目录,/mpf/XX作为父卷,该目录下存放着文件系统、子卷、配额的相关配置文件。
2.实际上是我们将一个btrfs类型的lun格式化成了文件系统
关于更多btrfs文件系统参见维基百科介绍:https://wiki.archlinux.org/index.php/Btrfs_(简体中文)
二、btrfs文件系统常用命令介绍
btrfs subvolume create [-i <qgroupid>] [<dest>/]<name> #创建子卷
btrfs subvolume delete [options] <subvolume> [<subvolume>...] #删除子卷
btrfs subvolume list [options] [-G [+|-]value] [-C [+|-]value] [--sort=gen,ogen,rootid,path] <path> #显示子卷列表
btrfs subvolume snapshot [-r] [-i <qgroupid>] <source> <dest>|[<dest>/]<name> #创建子卷快照
btrfs subvolume get-default <path> #获取子卷默认的文件系统
btrfs subvolume set-default <subvolid> <path> #设置默认系统给子卷
btrfs subvolume find-new <path> <lastgen> #列出btrfs文件系统中最近修改的文件,结合find命令
btrfs subvolume show <subvol-path> #显示更多的子卷信息
btrfs subvolume sync <path> [<subvol-id>...] #子卷同步,类似mount同步模式,内存数据同步到磁盘,有待查证。
btrfs filesystem df [options] <path> #显示挂载的文件系统详细信息。
btrfs filesystem show [options] [<path>|<uuid>|<device>|label] #显示创建文件系统的磁盘信息。
btrfs filesystem sync <path> #强制文件系统同步,
btrfs filesystem defragment [options] <file>|<dir> [<file>|<dir>...] #碎片整理
btrfs filesystem resize [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path> #btrfs文件系统在线扩展和缩减空间
btrfs filesystem label [<device>|<mount_point>] [<newlabel>] #改变btrfs文件系统卷标
btrfs filesystem usage [options] <path> [<path>..] #显示文件系统当前的使用信息。
三、btrfs文件系统PHP后台函数解析
1.页面获取函数enumerateFileSystem
注意:页面获取的属性都是从该文件系统父卷/mpf目录下读取,但是文件系统的可用容量是通过终端执行df /media *命令,然后进行数据处理获取的。
1.addFileSystem既是一个创建lun的过程,也是一个归属判断的过程,所谓的归属判断就是,在双控条件下,创建文件系统,默认在主控下创建,还有就是可以在页面指定在那个控制器上创建,在某一个控制器下创建的文件系统,其配置文件只允许在当前控制器下写,同时挂载也是同样只在所选的控制器挂载。
2.在初始化文件系统时,我们指定的uuid,所以在挂载项下面特意加了-U选项
3.初始化完成之后,挂载先挂载父卷,在挂载子卷
1.先卸载子卷,然后根据压缩重删的判断,卸载父卷,然后执行擦除文件系统的命令。
2.卸载完文件系统在调用c函数执行lun的删除,删除lun的流程双控状态下先删除非归属的然后删除归属的。
1.执行命令btrfs subvolume create /media/XX/XX ,配置文件存放位置
/mpf/XX/config/sub
6.获取配额树,通过读取配额树相关的配置文件获取。修改配额树通过sed 命令修改配额树相关的配置文件
7.创建配额函数createquotas
四、btrfs文件系统内核代码分析
1.对于Btrfs理解的重要部分便是理解keys和items是如何交互的,和各个类型的item的数据是如何编排格式的。Btrfs-debug-tree命令可以被用来打印ascii格式的btree结构,如果想要查看数据是如何在磁盘上排列的,这可能会非常有帮助。
Btrfs Terms
Btree
所有的元数据都被存放在磁盘上的一个btree中。Btrees存储key/item对。尽管使用了相同的代码来实现所有的btrees,但仍有一些不同种类的btree。可以参考 Btrees。
Key
一个用来为一棵Btree的item提供标识和分类的固定大小的元组。key被分成3各部分:objectid, type, 和 offset。type字段显示另外两个字段应该被使用的方式和在item中找到的信息类型。可以参考Btree Keys。
Item
存储在btree叶子中的可变大小的结构。根据key类型的不同,item含有不同类型的数据。可以参考Btree Items。
Subvolume
一个含有文件和目录的命名树。每一个快照是一个subvolume,但并不是每一个subvolume都是一个快照。
Snapshot
通过引用另一个subvolume的根来创建一个subvolume。快照是可写的,但是对于快照的任何修改都不会出现在它的父subvolume中。
Extent buffer
一个允许访问大于一个页大小的btree块的抽象。
Main Source Files
ctree.c 核心的btree管理代码
ctree.h 定义了keys和大多数元数据使用的数据结构
dir-item.c 创建和使用目录items的辅助函数
disk-io.c 元数据IO操作和FS open/close 例程
extent-tree.c btree块和文件数据extents使用的tracks and space
extent_io.c 跟踪状态(locked, writeback 等)和实现extent_buffers
extent_map.c 映射一个文件的逻辑偏移到磁盘上的逻辑块地址
file-item.c 插入和移除文件extents 和数据校验和的辅助函数
file.c 文件写例程(kernel only)
inode-item.c 在btree中分配inode结构的辅助函数
inode.c kernel使用的大部分文件和目录操作
ordered-data.c 为data=ordered 维护inodes链表
print-tree.c 查找一棵btree并打印它找到的items
root-tree.c 管理tree roots的tree中的items的辅助函数
struct-funcs.c 例示所有的元数据的set/get 函数的宏
super.c 内核超级块及相关函数
transaction.c 处理事件的提交
volumes.c 所有的多设备有关代码
tree-log.c 为快速fsync 处理树items的日志
compression.c zlib压缩支持例程
2.文件系统的创建代码运行流程
位置文件 文件作用
btrfs_mount fs/btrfs ->super.c 内核超级块及相关函数
|
btrfs_fill_super fs/btrfs ->super.c
|
open_ctree disk-io.c 元数据IO操作和FS open/close 例程
|
btrfs_start_transtions transaction.c btrfs_create_uuid_tree volumes.c 所有的多设备有关代码
|
处理事件的提交
|
start_transation transaction.c
|
btrfs_block_rsv_add extent_tree.c btree块和文件数据extents使用的tracks and space
|
reserve_metadata_bytes extent_tree.c
1.btrfs_mount通过sget获取到超级快中的信息传给btrfs_fill_super中。
2.在函数btrfs_fill_super中对超级快中的一些元素做了赋值操作,经过赋值操作后的超级快信息传给open_ctree函数。
3.在open_ctree函数中,将前一个函数传递过来的超级快的结构体信息传给block_sb函数,经过block_sb函数的处理,返回超级快结构体信息中s_fs_info元素信息,在open_ctree中用结构体btrfs_fs_info *fs_info来接收。
4.将fs_info传递给btrfs_create_uuid_tree函数,
取struct btrfs_fs_info *fs_info中的子结构体struct btrfs_root *tree_root传给btrfs_start_transaction函数 ,然后传递给start_transaction函数,同时传递给start_transaction函数的还有start_transaction信号和flush的初始值。
5.在start_transaction函数中调用btrfs_block_rsv_add函数,传递给该函数的
第一个参数为整个tree_root结构体,第二个参数为tree_root结构体中子结构体中的btrfs_fs_info结构体的子结构体btrfs_block_rsv结构体,第四个参数
为上一级传递的flush的默认值。在btrfs_block_rsv_add函数中将上一级传递过来的值同样传递给reserve_metadata_bytes。
6.在函数reserve_metadata_bytes中取
结构体btrfs_block_rsv的子结构体btrfs_space_info,然后根据从该结构体中取到的值进行比较
7.文件系统后台创建过程中,单位是以B为单位。
注:本文中类似/media/XX /mpf/XX其中XX代表的是具体的文件系统名称。
参考连接:
https://blog.csdn.net/PANGHAIFEI/article/details/99848825
https://blog.csdn.net/tanbajiong6117/article/details/38180707
https://blog.csdn.net/lcw_202/article/details/7311088
2020.4.16 swk
原文:https://www.cnblogs.com/swk123/p/12841770.html