Skip to content

Commit 1f22f4d

Browse files
boryaskdave
authored andcommitted
btrfs: fix iteration bug in __qgroup_excl_accounting()
__qgroup_excl_accounting() uses the qgroup iterator machinery to update the account of one qgroups usage for all its parent hierarchy, when we either add or remove a relation and have only exclusive usage. However, there is a small bug there: we loop with an extra iteration temporary qgroup called `cur` but never actually refer to that in the body of the loop. As a result, we redundantly account the same usage to the first qgroup in the list. This can be reproduced in the following way: mkfs.btrfs -f -O squota <dev> mount <dev> <mnt> btrfs subvol create <mnt>/sv dd if=/dev/zero of=<mnt>/sv/f bs=1M count=1 sync btrfs qgroup create 1/100 <mnt> btrfs qgroup create 2/200 <mnt> btrfs qgroup assign 1/100 2/200 <mnt> btrfs qgroup assign 0/256 1/100 <mnt> btrfs qgroup show <mnt> and the broken result is (note the 2MiB on 1/100 and 0Mib on 2/100): Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv 1/100 2.03MiB 2.03MiB 2/100<1 member qgroup> 2/100 0.00B 0.00B <0 member qgroups> with this fix, which simply re-uses `qgroup` as the iteration variable, we see the expected result: Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv Qgroupid Referenced Exclusive Path -------- ---------- --------- ---- 0/5 16.00KiB 16.00KiB <toplevel> 0/256 1.02MiB 1.02MiB sv 1/100 1.02MiB 1.02MiB 2/100<1 member qgroup> 2/100 1.02MiB 1.02MiB <0 member qgroups> The existing fstests did not exercise two layer inheritance so this bug was missed. I intend to add that testing there, as well. Fixes: a0bdc04 ("btrfs: qgroup: use qgroup_iterator in __qgroup_excl_accounting()") Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Boris Burkov <[email protected]>
1 parent 3b19db2 commit 1f22f4d

File tree

1 file changed

+1
-2
lines changed

1 file changed

+1
-2
lines changed

fs/btrfs/qgroup.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,6 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
14531453
struct btrfs_qgroup *src, int sign)
14541454
{
14551455
struct btrfs_qgroup *qgroup;
1456-
struct btrfs_qgroup *cur;
14571456
LIST_HEAD(qgroup_list);
14581457
u64 num_bytes = src->excl;
14591458
int ret = 0;
@@ -1463,7 +1462,7 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
14631462
goto out;
14641463

14651464
qgroup_iterator_add(&qgroup_list, qgroup);
1466-
list_for_each_entry(cur, &qgroup_list, iterator) {
1465+
list_for_each_entry(qgroup, &qgroup_list, iterator) {
14671466
struct btrfs_qgroup_list *glist;
14681467

14691468
qgroup->rfer += sign * num_bytes;

0 commit comments

Comments
 (0)