存储那些事儿(五):BTRFS文件系统之Btree结构详解
Btree数据结构可以说是BTRFS文件系统的基础。它提供了一个通用的方式去存储不同的数据类型。它仅仅存储3个数据类型:key, item和block header。
btrfs_header的定义如下:
struct btrfs_header {
u8 csum[32];
u8 fsid[16];
__le64 blocknr;
__le64 flags;
u8 chunk_tree_uid[16];
__le64 generation;
__le64 owner;
__le32 nritems;
u8 level;
}
btrfs_disk_key的定义如下:
struct btrfs_disk_key {
__le64 objectid;
u8 type;
__le64 offset;
}
btrfs_item的定义如下:
struct btrfs_item {
struct btrfs_disk_key key;
__le32 offset;
__le32 size;
}
对于b-tree的非叶子节点,它仅仅保存了[Key, block-pointer]。而叶子(Leaf)节点则保存了[item, data]。data的大小是不固定的。leaf在开始的地方保存了items的一个数组。而在结尾则以反方向保存了data的数组。这两个数组是向中间增长的。结构体btrfs_item.offset保存了data的偏移量,而btrfs_item.size则保存了data的大小。下面的图可以形象的说明这个问题:
item的data大小是不固定的。并且对于不同的数据结构,这个data的类型也是不一样的。struct btrfs_disk_key::type则说明了data的不同类别。
btrfs_header保存了这个节点数据的一个checksum,拥有这个节点的文件系统的id,这个节点在树中的level,这个节点所占用的block数目。这些成员数据可以在读取数据的时候对元数据进行验证。对于指向这个btree 节点的所有者来说,它会存储generation的值,这能够保证元数据的正确性。
对于指向下层节点的node指针来说,为了简化文件回写的逻辑,下层节点的checksum并不会被保存。generation在节点插入btree时已经被计算出了,但是checksum则仅仅在将这个数据块写回到disk时才会计算。因此,使用generation将会使得Btrfs检测到错误的回写。如果使用checksum,那么由于下层节点的checksum仅仅在会写到disk时才会计算,那么计算得到checksum后不得不修改上层指向该节点的checksum,非常低效。
那么generation是怎么计算出来的?就是分配当前节点的transaction id。这样也使得增量备份变得简单。当然了,这个transaction id是被COW的transaction子系统使用的。
对于struct btrfs_key.objectid来说,它唯一标识了该逻辑单元,或者叫object。BTRFS就是由这些objects构成的。当object创建时,一个未被其他object使用的object id就会赋给它。objectid可以说是key中最重要的元素。通过objectid,所有的object 都可以组织到b-tree中。
inode
inode是存在struct btrfs_inode_item中的,其中key.offset == 0 并且 key.type == 1。inode的item肯定都是最前面;它们保存了传统文件和目录的状态信息。它相对来说很小,并且不包含内嵌的文件数据或者扩展的属性。这些信息都是保存到其他类型的item中的。
文件
小文件如果可以放到一个leaf 节点的话,它是有可能会被放到扩展的item中的。在这种情况下,key.offset保存了文件数据的在extent中的offset;在btrfs_item.size保存了这个文件的大小。这种文件成为inline file,这种文件由于减少了寻址和IO,因此非常快。
对于大文件来说,它们是存到extent中的。struct_file_extent_item存储了这个extent的generation number 和一个[ disk block, disk num blocks ]数对以记录这个文件存储到的磁盘位置。
尊重原创,转载请注明出处 anzhsoft: http://blog.csdn.net/anzhsoft/article/details/20382885
参考资料:
1. https://btrfs.wiki.kernel.org/index.php/Btrfs_design
2. BTRFS: The Linux B-tree Filesystem - IBM Research
存储那些事儿(五):BTRFS文件系统之Btree结构详解的更多相关文章
- Linux文件系统的目录结构详解
Linux文件系统的目录结构详解 一.前 言 文章对Linux下所有目录一一说明,对比较重要的目录加以重点解说,以帮助初学者熟练掌握Linux的目录结构. 二.目 录 1.什么是文件系统 2.文件 ...
- 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解
http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...
- 前端数据存储方案集合(cookie localStorage等)以及详解 (二)
前端数据存储方案集合(cookie localStorage等)以及详解 (二) 在之前的文章中已经介绍到了 前端存储方案中的 cookie . 但是 cookie 的存储上限是 4KB. 如果超过了 ...
- “全栈2019”Java第五十四章:多态详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第五十章:继承与构造方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!
大家好,我是老三,面渣逆袭系列继续,这节我们来搞定Redis--不会有人假期玩去了吧?不会吧? 基础 1.说说什么是Redis? Redis是一种基于键值对(key-value)的NoSQL数据库. ...
- Redis进阶实践之十五 Redis-cli命令行工具使用详解第二部分(结束)
一.介绍 今天继续redis-cli使用的介绍,上一篇文章写了一部分,写到第9个小节,今天就来完成第二部分.话不多说,开始我们今天的讲解.如果要想看第一篇文章,地址如下:http: ...
- 开源项目SMSS发开指南(五)——SSL/TLS加密通信详解(下)
继上一篇介绍如何在多种语言之间使用SSL加密通信,今天我们关注Java端的证书创建以及支持SSL的NioSocket服务端开发.完整源码 一.创建keystore文件 网上大多数是通过jdk命令创建秘 ...
- Hadoop分布式文件系统(HDFS)详解
HDFS简介: 当数据集的大小超过一台独立物理计算机的存储能力时,就有必要对它进行分区 (partition)并存储到若干台单独的计算机上.管理网络中跨多台计算机存储的文件系统成为分布式文件系统 (D ...
随机推荐
- diango-团队介绍
1.使用django-admin startproject show创建项目,并使用python manage.py startapp team_show创建应用 2.进行相关的配置 3.代码的实现
- IP地址段遍历
#region 搜索ftp服务器地址 /// <summary> /// 搜索ftp服务器 /// </summary> public void SearchFtpServer ...
- python笔记十二(匿名函数)
一.匿名函数 有些情况下,我们需要把函数当做参数传入到另外的函数中,或者是把函数作为某个函数的返回值,此时我们就可以使用匿名函数. 匿名函数的标志是lambda. >>> f = ...
- fatal error C1083: Cannot open precompiled header file: 'Debug/xxoo.pch': No such file or directory
fatal error C1083: Cannot open precompiled header file: 'Debug/xxoo.pch': No such file or directory ...
- LOG4J日志级别详解
日志记录器(Logger)是日志处理的核心组件. org.apache.log4j.Level类提供以下级别,但也可以通过Level类的子类自定义级别. Level 描述 ALL 各级包括自定义级别 ...
- 20160217.CCPP体系详解(0027天)
程序片段(01):TestCmd.c 内容概要:管道_字符串 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include < ...
- 20160212.CCPP体系详解(0022天)
程序片段(01):01.二维数组.c 内容概要:二维数组 #include <stdio.h> #include <stdlib.h> //01.关于栈内存开辟数组: // 诀 ...
- Linux系统中查询发行版本号以及内核版本的命令总结
了解Linux发行版本的版本号是一项非常重要的事情,大多数软件对系统的版本都有要求,发行版本号与软件不匹配,软件将无法安装或者无法使用.这边集合市面上流行的Linux发行版本版本号查询方法.有了这边文 ...
- PHP Ajax JavaScript 实现 无刷新附件上传
普通表单 前端页面 后台处理 带有文件的表单 刷新方式 前端界面 后台页面 无刷新方式 大文件上传 POST极值 upload极值 上传细节 前端页面 后台处理 总结 对一个网站而言,有一个基本的不可 ...
- SQL LOADER使用
转自huan.gu专栏:http://blog.csdn.net/gh320/article/details/17048907 1.执行的命令 sqlldr 数据库用户名/密码 control=控制文 ...