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

简介: 介绍Linux中文件系统扩展属性xattr特性的基本概念,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有自己的64bitobject_id。每个object可以有若干不同类型的itemitemkey由三部分构成:object_idtype标识item的类型,offset标识item在object中的偏移量。

文件object:

item

功能

Key type

Key offset

Inode item

inode

BTRFS_INODE_ITEM_KEY

0

extent data item

存储文件数据

BTRFS_EXTENT_DATA_KEY

该数据块在文件中的offset

...




目录object:

item

功能

Key type

Key offset

Inode item

inode

BTRFS_INODE_ITEM_KEY

0

dir item

根据文件名查找文件的object_id

BTRFS_DIR_ITEM_KEY

64 bit filename hash

index item

文件遍历

BTRFS_DIR_INDEX_KEY

Inode Sequence number

Xattr item

扩展属性

BTRFS_XATTR_ITEM_KEY

64 bit filename hash

...







btrfs xattr支持

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

Struct btrfs_disk_key

transid

data_len

name_len

type

name

data

obj_id | BTRFS_XATTR_ITEM_KEY | hash("test")


3

13

BTRFS_FT_XATTR

"user.testattr"

"abc"

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

btrfs_setxattr为例:

btrfs_insert_xattr_item    插入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    匹配dir_item是否有要找的xattr

//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);
}


参考

wiki/Btrfs

btrfs.wiki.kernel.org/Btrfs_design

btrfs.wiki.kernel.org/Data_Structures.html

btrfs.wiki.kernel.org/On-disk_Format.html

btrfs.wiki.kernel.org/Trees.html


Filesystem Btree-BTRFS extent-CSDN

新一代 Linux 文件系统 btrfs 简介

Linux 文件系统扩展属性 xattr-cnblog


目录
相关文章
|
2天前
|
存储 Java Linux
常见的文件系统类型及其特点
常见的文件系统类型及其特点
|
2月前
|
存储 文件存储
文件系统设计与实现上
文件系统设计与实现上
64 6
文件系统设计与实现上
|
2月前
|
安全 测试技术
文件系统设计与实现下
文件系统设计与实现下
49 2
|
2月前
|
存储
文件系统设计与实现中
文件系统设计与实现中
31 0
系统诊断小技巧(9):如何从Ext3或者Ext4文件系统推断分区位置
扩容失败或者系统重启后分区丢失,需要文件系统推定分区位置。我们这里给出一个自动化的工具
2236 0
|
存储 文件存储 安全