源文件
linux/fs/btrfs/ctree.h
linux/fs/btrfs/free-space-cache.c
free cluster 是在 free space cache 的基础上实现的。随着分配/释放的进行,一段空闲空间会变得不连续,这种情况下,可能多个碎片化的空间总和比较大,可以将多段空闲空间一起管理,满足大空间分配。
数据结构
1 /* 2 * free clusters are used to claim free space in relatively large chunks, 3 * allowing us to do less seeky writes. They are used for all metadata 4 * allocations and data allocations in ssd mode. 5 */ 6 struct btrfs_free_cluster { 满足分配,需要多个空闲空间表项来支持,因此称为 cluster;这些 entry 属同一个 bg 7 spinlock_t lock; 8 spinlock_t refill_lock; 9 struct rb_root root; 管理用于支持本分配的 struct btrfs_free_space 表项 10 这些表项在从 block_group->free_space_ctl 中找到后,断开,然后加入该 tree 11 /* largest extent in this cluster */ 12 u64 max_size; 在找到的一组空闲空间中,最大的连续空闲区域 13 /* first extent starting offset */ 14 u64 window_start; 在找到的一组空闲空间中,第 1 个连续空闲空间的起始地址 15 struct btrfs_block_group_cache *block_group; 16 /* 17 * when a cluster is allocated from a block group, we put the 18 * cluster onto a list in the block group so that it can 19 * be freed before the block group is freed. 20 */ 21 struct list_head block_group_list; 22 };
在 free cluster 中,单个空闲空间还是由 struct btrfs_free_space 来表示,只是这些表项不再链接到对应 struct btrfs_free_space_ctl 的 rbtree,而是由 struct btrfs_free_cluster 通过 rbtree 来管理。有了 free space cache 的支持,free cluster 实现起来简单了很多,数据结构上只需要对 struct btrfs_free_space 表项进行组织就可以了。
对于空间空间的计算,统计量还是计算在 struct btrfs_free_space_ctl 内的,变化的只是 struct btrfs_free_space 表项的链接关系;如果使用了某个表项,则空间空间统计量会更新到 struct btrfs_free_space_ctl 中。
struct btrfs_free_cluster 通过 block_group 字段可以找到对应的 bg,进而通过 bg 的 ->free_space_ctl 字段访问到对应的 struct btrfs_free_space_ctl。
对于 extent/bitmap 表项,在第一篇中提过:”从关于 free space cluster 的 commit 中可以看到,当前,对于一个 cluster 来说,要么有 extent,要么有 bitmap,不可两者共有“
Currently we either want to refill a cluster with 1) All normal extent entries (those without bitmaps) 2) A bitmap entry with enough space
虽然数据结构是通用的,但是只是为将来扩展留下了空间;当前实际使用中关系还是比较简单的。
基本操作
释放 cluser 空间:btrfs_return_cluster_to_free_space
从 free cluster 中分配空间:btrfs_alloc_from_cluster
分配空间的时候,是从 free cluster 中管理的 entry 表项中进行调整,来表示空间分配的,更新的统计量也是 struct btrfs_free_space_ctl 的。
构造 free cluster:btrfs_find_space_cluster
搜索 free space cache,如果能满足分配要求,则将 entry 表项组织到 cluser 中;每个 entry 的空间需要满足分配的最小连续空闲空间的要求
* 尚未弄明白的问题
* 一个 block_group 会同时挂载多少个 struct btrfs_free_cluster?
私信问过 Josef Bacik:
Currently there should only be one cluster on a block group, we don't do multiple clusters at the moment.
And we only have one bitmap at a time in a cluster that has bitmaps.
这样看来,虽然都使用 rbtree 来组织,但是当前都是 1v1v1 的关系,只是为将来扩展留好了空间。
有 bitmap 的 cluster 空间 >= BIT_PER_BITMAP * ctl->unit 大小,因为还有 extent 表项的支持
* 什么场景下会使用 free cluster 来支持分配?