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


目录
相关文章
|
存储 算法 数据库
BTRFS - A Forest,extent分配树,同步与并发
介绍Btrfs如何由树木森林构成。
224 3
|
存储 算法 Linux
打破常规,Linux内核新的数据结构上场maple tree(下)
打破常规,Linux内核新的数据结构上场maple tree
|
Shell Android开发
ADB更改Android设备屏幕显示方向
ADB更改Android设备屏幕显示方向
830 5
|
存储 索引
Btrfs 文件树
介绍Btrfs中FS Tree的结构。
144 1
Btrfs 文件树
|
存储 芯片
Rockchip 自定义vendorstorages数据再u-boot通过cmdline给kernel传递数据
Rockchip 自定义vendorstorages数据再u-boot通过cmdline给kernel传递数据
982 1
|
Dubbo Java 应用服务中间件
Dubbo 3.3.0-beta 版本正式发布
近日,Apache Dubbo 发布了 3.3 分支大版本 3.3.0-beta.1,相较于 3.2 系列版本,3.3.0-beta 引入了一些重量级的功能升级,按照社区规划,3.3 也将是 Dubbo3 非常重要的一个里程碑大版本,在 3.3.0 首个正式版本之后 Dubbo3 将正式进入长期稳定维护态,即标志着 Dubbo3 作为面向云原生时代的下一代微服务框架将具备规划的所有核心功能。
|
API Android开发
Android11.0(R) framework 新增类 lint 编码检查问题
Android11.0(R) framework 新增类 lint 编码检查问题
1603 0
|
开发工具 开发者 iOS开发
使用香蕉云编创建ios打包证书的教程
使用mac创建ios证书,需要购买mac电脑,成本非常高,因此我这里教会大家使用香蕉云编来创建ios打包证书
3310 1
使用香蕉云编创建ios打包证书的教程
|
Rust 算法 NoSQL
【密码学】一文读懂MT19937
瞄了一眼redis的源码,然后发现里面好玩的东西还挺多的,本文来聊一聊redis当中用到的一个随机数生成算法 mt19937,具体源码参见文末的参考资料,在这里就不贴到文本当中了。对于redis源码里面用的是mt19937-64本文先来看一下32位的版本,对于64位的版本,只不过状态当中元素用的是64位的元素,整个运算过程框架是类似的。 「梅森旋转算法」(「Mersenne twister」)是一个伪随机数生成算法,由松本真和西村拓士在1997年提出来的,可以快速产生高质量的伪随机数,修正了古典随机数生成算法当中的很多缺陷。19937这个名字来源于周期长度为梅森素数 。
2089 0
【密码学】一文读懂MT19937