详解btrfs中文件系统扩展属性xattr的实现

本文介绍了Linux文件系统中的Btrfs扩展属性(xattr)的概念、在Btrfs设计中的应用,以及如何使用btrfs_setxattr、getxattr、removexattr和listxattr等函数进行操作。详细解释了Btrfs中文件和目录对象的item结构,以及xattr在目录项中的存储方式。
摘要由CSDN通过智能技术生成

btrfs xattr

linux 文件系统扩展属性 xattr

扩展属性(Extended Attributes,简称 xattr)支持给文件添加用户自定义的额外属性(Key-value 的键值对)

setfattr -n user.testattr -v abc test #设置test文件user.testattr属性为"abc"
getfattr -n user.testattr test # 读取test文件的user.testattr属性 
setfattr -x user.testattr test  # 删除test文件的user.testattr属性
attr -lq test # 列举test文件的属性

Btrfs Design

Btrees Introduction

在 btrfs(B-tree File System) 文件系统中,所有的 metadata 都由 BTree 管理。

文件系统由树木森林构造,superblock 指向构成文件系统的所有 B 树:

  • FS Tree:管理文件相关的元数据,如 inode,dir 等;
  • Chunk tree:管理磁盘设备,每一个磁盘设备都在 Chunk Tree 中有一个 item ;
  • Extent Tree:管理磁盘空间分配,btrfs 每分配一段磁盘空间,便将该磁盘空间的信息插入到 Extent tree。通过查询 Extent Tree 得到空闲的磁盘空间信息;
  • Checksum Tree:保存数据块的校验和。

请添加图片描述

Btree Data structure

FS Tree 为例:

结点分为内部结点和叶子结点

内部结点只用于查找,不存储数据,仅仅持有[key,block-pointer]对。

叶子结点持有[item,data]键值对。叶子结点分为 headeritem 数组和 data 数组两个部分。item 由头向尾生长,data 由尾向头生长。根据 item 中的 offsetsize 字段可以找到其对应的 dataitem 中的 key 标识一个唯一的 item
请添加图片描述

文件系统由 object 构成(文件、目录等),每个 object 有自己的 64bit object_id。每个 object 可以有若干不同类型的 itemitemkey 由三部分构成:object_idtype 标识 item 的类型,offset 标识 item 在 object 中的偏移量。

文件 object:

item功能Key typeKey offset
Inode iteminodeBTRFS_INODE_ITEM_KEY0
extent data item存储文件数据BTRFS_EXTENT_DATA_KEY该数据块在文件中的 offset

目录 object:

item功能Key typeKey offset
Inode iteminodeBTRFS_INODE_ITEM_KEY0
dir item根据文件名查找文件的 object_idBTRFS_DIR_ITEM_KEY64 bit filename hash
index item文件遍历BTRFS_DIR_INDEX_KEYInode Sequence number
Xattr item扩展属性BTRFS_XATTR_ITEM_KEY64 bit filename hash

请添加图片描述

btrfs xattr 支持

Btrfs 将扩展属性以 Xattr item 形式维护,存储在目录的 items 中,类似于一个目录项,复用 dir item 数据结构。

在这里插入图片描述

Struct btrfs_disk_keytransiddata_lenname_lentypenamedata
obj_idBTRFS_XATTR_ITEM_KEYhash(“test”)313BTRFS_FT_XATTR

btrfs_setxattrbtrfs_getxattrbtrfs_removexattrbtrfs_listxattr 分别对应设置扩展属性、读取扩展属性、删除扩展属性、列举扩展属性。

btrfs_setxattr 为例:

在这里插入图片描述

btrfs_insert_xattr_item:

leaf = path->nodes[0];
btrfs_cpu_key_to_disk(&disk_key, &location);
// write key
btrfs_set_dir_item_key(leaf, dir_item, &disk_key);    
btrfs_set_dir_type(leaf, dir_item, BTRFS_FT_XATTR); 
   
btrfs_set_dir_name_len(leaf, dir_item, name_len);     // write name_len
btrfs_set_dir_transid(leaf, dir_item, trans->transid);
btrfs_set_dir_data_len(leaf, dir_item, data_len);    // write data_len
name_ptr = (unsigned long)(dir_item + 1);
data_ptr = (unsigned long)((char *)name_ptr + name_len);

write_extent_buffer(leaf, name, name_ptr, name_len); // write name of xattr
write_extent_buffer(leaf, data, data_ptr, data_len); // write data of xattr
btrfs_mark_buffer_dirty(path->nodes[0]);

btrfs_match_dir_item_name:

//walks through all the entries in a dir item and finds one for a specific name
leaf = path->nodes[0];
dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
total_len = btrfs_item_size_nr(leaf, path->slots[0]);
while (cur < total_len) {
        this_len = sizeof(*dir_item) +
                btrfs_dir_name_len(leaf, dir_item) +
                btrfs_dir_data_len(leaf, dir_item);
        name_ptr = (unsigned long)(dir_item + 1);
        if (btrfs_dir_name_len(leaf, dir_item) == name_len &&
            memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)    // find matched xattr
                return dir_item;
        cur += this_len;
        dir_item = (struct btrfs_dir_item *)((char *)dir_item +
                                             this_len);
}
  • 38
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值