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结构详解的更多相关文章

  1. Linux文件系统的目录结构详解

    Linux文件系统的目录结构详解   一.前 言 文章对Linux下所有目录一一说明,对比较重要的目录加以重点解说,以帮助初学者熟练掌握Linux的目录结构. 二.目 录 1.什么是文件系统 2.文件 ...

  2. 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解

    http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...

  3. 前端数据存储方案集合(cookie localStorage等)以及详解 (二)

    前端数据存储方案集合(cookie localStorage等)以及详解 (二) 在之前的文章中已经介绍到了 前端存储方案中的 cookie . 但是 cookie 的存储上限是 4KB. 如果超过了 ...

  4. “全栈2019”Java第五十四章:多态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. “全栈2019”Java第五十章:继承与构造方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. 面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!

    大家好,我是老三,面渣逆袭系列继续,这节我们来搞定Redis--不会有人假期玩去了吧?不会吧? 基础 1.说说什么是Redis? Redis是一种基于键值对(key-value)的NoSQL数据库. ...

  7. Redis进阶实践之十五 Redis-cli命令行工具使用详解第二部分(结束)

    一.介绍           今天继续redis-cli使用的介绍,上一篇文章写了一部分,写到第9个小节,今天就来完成第二部分.话不多说,开始我们今天的讲解.如果要想看第一篇文章,地址如下:http: ...

  8. 开源项目SMSS发开指南(五)——SSL/TLS加密通信详解(下)

    继上一篇介绍如何在多种语言之间使用SSL加密通信,今天我们关注Java端的证书创建以及支持SSL的NioSocket服务端开发.完整源码 一.创建keystore文件 网上大多数是通过jdk命令创建秘 ...

  9. Hadoop分布式文件系统(HDFS)详解

    HDFS简介: 当数据集的大小超过一台独立物理计算机的存储能力时,就有必要对它进行分区 (partition)并存储到若干台单独的计算机上.管理网络中跨多台计算机存储的文件系统成为分布式文件系统 (D ...

随机推荐

  1. Redis数据库之概念与创建服务

      概念                                  Remote   Dictionary  Server key-value  数据库存储系统,数据结构服务器. 键是Stri ...

  2. angular+ionic前后端分离开发项目中的使用

    Ionic基于AngularJS构建而成,所以学习一些AngularJS的知识很有必要.Ionic并没有独立开发一套完整的Web应用框架,而是对AngularJS进行了扩展,给它添加了大量界面组件和其 ...

  3. Thread 调用方法的方式

    1.传统ThreadStart 2.ParameterizedThreadStart 3.委托thread = new Thread(delegate() { NoticeBroadcast(user ...

  4. Node.js 集群

    稳定性: 2 - 不稳定 单个 Node 实例运行在一个线程中.为了更好的利用多核系统的能力,可以启动 Node 集群来处理负载. 在集群模块里很容易就能创建一个共享所有服务器接口的进程. var c ...

  5. Java第5次实验提纲(Java图形界面编程)

    1. Swing与NetBeans 使用NetBeans编写简单界面.见GUI实验参考文件中的0.第06次实验(图形程序设计.事件处理与Swing).doc 题目1: Swing用户界面组件与事件处理 ...

  6. GDAL C#读取shp中文属性值乱码问题

    GDAL的C#版本读取shp中,如果属性值中含有中文,读出来有可能是乱码的问题,根据SWIG生成的C#代码调试发现问题所在,在Ogr.cs文件中有这么一个函数,代码如下: internal stati ...

  7. Bootstrap3 排版-标题

    HTML 中的所有标题标签,<h1> 到 <h6> 均可使用.另外,还提供了 .h1 到 .h6 类,为的是给内联(inline)属性的文本赋予标题的样式. h1. Boots ...

  8. 修改hosts立刻生效不必重启

    有时我们会通过修改Hosts文件(路径为系统盘:\WINDOWS\system32\drivers\etc\hosts),在修改并保存Hosts文件后需要重启才能使设置生效. 这时可以打开命令提示符 ...

  9. MFC误报内存泄露的修复

    在debug状态退出程序的时候,VS会在输出窗口列出可能的内存泄露的地方. MFC中使用DEBUG_NEW能够更方便的定位泄露的地点.但假如MFC的dll释放""过早"& ...

  10. NestedScrollView嵌套ViewPager

    NestedScrollView嵌套ViewPager 效果图 重写ViewPager package com.kongqw.kbox.view; import android.content.Con ...