zoukankan      html  css  js  c++  java
  • 存储那些事儿(五):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


  • 相关阅读:
    c# Task多线程并行任务中等待所有线程都执行完成
    C#多线程之所有线程执行完成后
    正则表达式
    js 实时监听input中值变化
    js中prop和attr区别
    获取自定义属性
    checkBox
    js中判断数组中是否包含某元素的方法
    leetcode — path-sum-ii
    leetcode — path-sum
  • 原文地址:https://www.cnblogs.com/anzhsoft/p/3602948.html
Copyright © 2011-2022 走看看