qgroup type in btrfs

Recently, I sent a set of patches to btrfs community for qgroup to make quota working much better.


NOTE, before this patchset, I have sent a lot of patches for bug-fix about quota in btrfs.


(1). Probem: user found quota did not reach the limit but can not write any more.

       Example:

Script:
mkfs.btrfs /dev/sdc -f
mount /dev/sdc /mnt
btrfs quota enable /mnt
btrfs quota rescan /mnt
sync
btrfs sub create /mnt/sub
btrfs qgroup limit -e 10M /mnt/sub
dd if=/dev/zero of=/mnt/sub/data bs=$((1024)) count=10240000000
sync
btrfs qgroup show -prce /mnt

Result:
dd: error writing ‘/mnt/sub/data’: Disk quota exceeded
10174+0 records in
10173+0 records out
10417152 bytes (10 MB) copied, 0.0356769 s, 292 MB/s
-rw-r--r--. 1 root root 10417152 Mar 22 08:49 /mnt/sub/data
qgroupid         rfer         excl     max_rfer     max_excl parent  child 
--------         ----         ----     --------     -------- ------  ----- 
0/5          16.00KiB     16.00KiB        0.00B        0.00B ---     ---  
0/257         9.95MiB      9.95MiB        0.00B     10.00MiB ---     ---  
0/258        16.00KiB     16.00KiB        0.00B        0.00B ---     ---  

It's very confusing to user, that "I limited my subvolume with 10M, and I found the quota number of

it is 9.95M, but I can't write any byte into it."


(2). Reason: qgroup in btrfs only account and limit size both of data and metadata.


That said, when a user want to write something into subvolume, btrfs will reserve some

metadata for it. Although what you want to write is not out of the limit, but the size of data and metadata

is out of the limit.


(3). Solution: account and limit data and metadata separately.


(a). I restructed the btrfs_qgroup in memory:

btrfs_qgroup:                                     |-------------|
-----------------                                 |rfer         |
|data_info      |--------------->btrfs_qgroup_info|rfer_cmpr    |
|metadata_info  |                                 |excl         |
|               |                                 |excl_cmpr    |
|data_limits    |                                 ---------------
|metadata_limits|
|mixed_limits   |--------------->btrfs_qgroup_limits|-------------
|-------------- |                                   |lim_flags  |
                                                    |max_rfer   |
                                                    |max_excl   |
                                                    |rsv_rfer   |
                                                    |rsv_excl   |
                                                    ------------
In this way, we can store the information for data and metadata separately.
And we can limit then in three ways: data_limits, metadata_limits and mixed_limits.

(b). I have to add a incompatability feature for it.
I reuse the objectid to search btrfs_qgroup_info_item.

------------------------------------              ------------------------------------------------
|0 |BTRFS_QGROUP_INFO_KEY |qgroupid| ------------>|TYPE_OBJECTID |BTRFS_QGROUP_INFO_KEY |qgroupid|
------------------------------------              ------------------------------------------------

And introduce two macros for different type of infos.

	#define BTRFS_QGROUP_DATA_INFO_OBJECTID 1ULL
	#define BTRFS_QGROUP_METADATA_INFO_OBJECTID 2ULL
There is a similar change for limits.

(c). Testing.
	Hi Chris and David, as what I mentioned in a offline mail, there is a url for merging or
testing.
	btrfs: https://yangdongsheng  github.com/yangdongsheng/linux.git qgroup_type_v2
  btrfs-progs: https://yangdongsheng  github.com/yangdongsheng/btrfs-progs.git qgroup_type_v2

(1). btrfs/022 and btrfs/042
				kernel.v4.0-4c1		kernel.qgroup_type.patched
v3.19-rc2(progs)		 pass				pass
Patched(progs)			 pass				pass

(2). No qgroup type.
Script:
	# mkfs.btrfs  /dev/sdc -f
	# mount /dev/sdc /mnt
	# btrfs quota enable /mnt
	# btrfs quota rescan -w /mnt
	# btrfs sub create /mnt/sub
	# btrfs qgroup limit -e 10M 0/257 /mnt
	# dd if=/dev/zero of=/mnt/sub/data bs=1024 count=1000000
	# sync
	# btrfs qgroup show -prce --raw /mnt
Expected:
	dd: error writing '/mnt/sub/data': Disk quota exceeded
	10145+0 records in
	10144+0 records out
	10387456 bytes (10 MB) copied, 0.0368423 s, 282 MB/s
	qgroupid         rfer         excl     max_rfer     max_excl parent  child 
	--------         ----         ----     --------     -------- ------  ----- 
	0/5             16384        16384            0            0 ---     ---  
	0/257        10403840     10403840            0            0 ---     ---  

			kernel.v4.0-4c1.bugfix_patched		kernel.qgroup_type.patched
v3.19-rc2(progs)		 pass					pass
Patched(progs)			 pass					pass

(3) qgroup type.
Script:
	# mkfs.btrfs -O qgroup-type /dev/sdc -f
	# mount /dev/sdc /mnt
	# btrfs quota enable /mnt
	# btrfs quota rescan -w /mnt
	# btrfs sub create /mnt/sub
	# btrfs qgroup limit --type data -e 10M 0/257 /mnt
	# dd if=/dev/zero of=/mnt/sub/data bs=1024 count=1000000
	# sync
	# btrfs qgroup show -prce --raw --type data /mnt
	# btrfs qgroup show -prce --raw --type metadata /mnt
	# btrfs qgroup show -prce --raw --type mixed /mnt

			kernel.v4.0-4c1.bugfix_patched		kernel.qgroup_type.patched
v3.19-rc2(progs)	mkfs fail(no feature for qgroup-type)	mkfs fail(no feature for qgroup-type)
Patched(progs)		open_ctree failed. (Expected)			result as below. (pass)

Result:
	dd: error writing '/mnt/sub/data': Disk quota exceeded
	10241+0 records in
	10240+0 records out							  <------10240 means 10M
	10485760 bytes (10 MB) copied, 0.0331533 s, 316 MB/s
	qgroupid         rfer         excl     max_rfer     max_excl parent  child 
	--------         ----         ----     --------     -------- ------  ----- 
	0/5                 0            0            0            0 ---     ---  
	0/257        10485760     10485760            0     10485760 ---     ---  <------DATA info and limits
	qgroupid         rfer         excl     max_rfer     max_excl parent  child 
	--------         ----         ----     --------     -------- ------  ----- 
	0/5             16384        16384            0            0 ---     ---  
	0/257           16384        16384            0            0 ---     ---  <------METADATA info and limits
	qgroupid         rfer         excl     max_rfer     max_excl parent  child 
	--------         ----         ----     --------     -------- ------  ----- 
	0/5             16384        16384            0            0 ---     ---  
	0/257        10502144     10502144            0            0 ---     ---  <------MIXED info and limits

After all, you can use btrfs-debug-tree tool to show the details for each items.

你可能感兴趣的:(Btrfs)