btrfs-progs: mkfs: fix garbage in QGROUP_LIMIT
cover btrfs-progs: mkfs: fix garbage in QGROUP_LIMIT
Running "mkfs.btrfs -O quota" will result garbage values in QGROUP_LIMIT items.
This is inspired by recent tree-checker changes to check QGROUP_LIMIT and QGROUP_INFO.
And a new test case for it.
Qu Wenruo (2):
btrfs-progs: mkfs: fix garbage in the QGROUP_LIMIT item
btrfs-progs: tests: add test for zeroed QGROUP_LIMIT item from mkfs
mkfs/main.c | 6 ++++ .../046-qgroup-limit-zeroed/test.sh | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100755 tests/mkfs-tests/046-qgroup-limit-zeroed/test.sh
--
2.56.0
PATCH 1/2 btrfs-progs: mkfs: fix garbage in the QGROUP_LIMIT item
[BUG]
If using "-O quota" option of mkfs.btrfs, the resulted image will have garbage in the QGROUP_LIMIT item:
quota tree key (QUOTA_TREE ROOT_ITEM 0)
leaf 30474240 items 3 free space 16088 generation 11 owner QUOTA_TREE leaf 30474240 flags 0x1(WRITTEN) backref revision 1
item 0 key (0 QGROUP_STATUS 0) itemoff 16243 itemsize 40
version 1 generation 11 flags ON scan 0
item 1 key (0 QGROUP_INFO 0/5) itemoff 16203 itemsize 40
generation 10
referenced 16384 referenced_compressed 16384 exclusive 16384 exclusive_compressed 16384
item 2 key (0 QGROUP_LIMIT 0/5) itemoff 16163 itemsize 40
flags 500000
max_referenced 8388608 max_exclusive 8954665512184738474 rsv_referenced 5153854573009882032 rsv_exclusive 3
^^^^^^^^^^^^^^^^^^^
[CAUSE]
The QGROUP_INFO and QGROUP_LIMIT items are inserted using btrfs_insert_empty_item(), which will not do any cleanup for the new item, so it will reuse whatever is left in the tree block.
For QGROUP_INFO it's not a big deal as later repair_qgroups() will update the item, but QGROUP_LIMIT garbage is left there.
[FIX]
Zero the newly inserted empty items for both QGROUP_INFO and QGROUP_LIMIT.
--- mkfs/main.c | 6 ++++++ 1 file changed, 6 insertions(+)
mkfs/main.c +6 -0
@@ -897,6 +897,9 @@ static int insert_qgroup_items(struct btrfs_trans_handle *trans, ret =btrfs_insert_empty_item (trans, quota_root, &path, &key,sizeof (struct btrfs_qgroup_info_item )); +memset_extent_buffer (path.nodes[0 ],0 , +btrfs_item_ptr_offset (path.nodes[0 ], path.slots[0 ]), +btrfs_item_size (path.nodes[0 ], path.slots[0 ]));btrfs_release_path (&path);if (ret <0 )return ret;
@@ -906,6 +909,9 @@ static int insert_qgroup_items(struct btrfs_trans_handle *trans, key.offset = qgroupid; ret =btrfs_insert_empty_item (trans, quota_root, &path, &key,sizeof (struct btrfs_qgroup_limit_item )); +memset_extent_buffer (path.nodes[0 ],0 , +btrfs_item_ptr_offset (path.nodes[0 ], path.slots[0 ]), +btrfs_item_size (path.nodes[0 ], path.slots[0 ]));return ret; }
Signature · 1 line
2.56.0
PATCH 2/2 btrfs-progs: tests: add test for zeroed QGROUP_LIMIT item from mkfs
In reply to Qu WenruoAdd a mkfs test that creates a filesystem with '-O quota' and verifies all members of the QGROUP_LIMIT items are zero.
This covers the garbage fix in the previous commit.
--- .../046-qgroup-limit-zeroed/test.sh | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100755 tests/mkfs-tests/046-qgroup-limit-zeroed/test.sh
tests/mkfs-tests/046-qgroup-limit-zeroed/test.sh new file +30 -0
@@ -0,0 +1,30 @@ +#!/bin/bash +# Verify that mkfs -O quota zeroes all members of the QGROUP_LIMIT items. + +source "$TEST_TOP/common" || exit + +check_prereq mkfs.btrfs +check_prereq btrfs + +setup_root_helper +prepare_test_dev + +run_check $SUDO_HELPER "$TOP/mkfs.btrfs" -f -O quota "$TEST_DEV" + +# A good limit item should looks like: +# +# item 2 key (0 QGROUP_LIMIT 0/5) itemoff 16027 itemsize 40 +# flags 0 +# max_referenced 0 max_exclusive 0 +# rsv_referenced 0 rsv_exclusive 0 +output=$(run_check_stdout $SUDO_HELPER "$TOP/btrfs" inspect-internal dump-tree -t quota "$TEST_DEV" | \ + grep -A 3 "QGROUP_LIMIT") + +if [ -z "$output" ]; then + _fail "no QGROUP_LIMIT item found" +fi + +for member in flags max_referenced max_exclusive rsv_referenced rsv_exclusive; do + echo "$output" | grep -q -w "$member 0" || + _fail "QGROUP_LIMIT member $member is not zero" +done
Signature · 1 line
2.56.0