mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-12 01:20:14 +00:00
btrfs: qgroup: update all parent qgroups when doing quick inherit
[BUG]
There is a bug that if a subvolume has multi-level parent qgroups, and
is able to do a quick inherit, only the direct parent qgroup got
updated:
mkfs.btrfs -f -O quota $dev
mount $dev $mnt
btrfs subv create $mnt/subv1
btrfs qgroup create 1/100 $mnt
btrfs qgroup create 2/100 $mnt
btrfs qgroup assign 1/100 2/100 $mnt
btrfs qgroup assign 0/256 1/100 $mnt
btrfs qgroup show -p --sync $mnt
Qgroupid Referenced Exclusive Parent Path
-------- ---------- --------- ------ ----
0/5 16.00KiB 16.00KiB - <toplevel>
0/256 16.00KiB 16.00KiB 1/100 subv1
1/100 16.00KiB 16.00KiB 2/100 2/100<1 member qgroup>
2/100 16.00KiB 16.00KiB - <0 member qgroups>
btrfs subv snap -i 1/100 $mnt/subv1 $mnt/snap1
btrfs qgroup show -p --sync $mnt
Qgroupid Referenced Exclusive Parent Path
-------- ---------- --------- ------ ----
0/5 16.00KiB 16.00KiB - <toplevel>
0/256 16.00KiB 16.00KiB 1/100 subv1
0/257 16.00KiB 16.00KiB 1/100 snap1
1/100 32.00KiB 32.00KiB 2/100 2/100<1 member qgroup>
2/100 16.00KiB 16.00KiB - <0 member qgroups>
# Note that 2/100 is not updated, and qgroup numbers are inconsistent
umount $mnt
[CAUSE]
If the snapshot source subvolume belongs to a parent qgroup, and the new
snapshot target is also added to the new same parent qgroup, we allow a
quick update without marking qgroup inconsistent.
But that quick update only update the parent qgroup, without checking if
there is any more parent qgroups.
[FIX]
Iterate through all parent qgroups during the quick inherit.
Reported-by: Boris Burkov <boris@bur.io>
Fixes: b20fe56cd285 ("btrfs: qgroup: allow quick inherit if snapshot is created and added to the same parent")
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
7ee19a59a7
commit
68d4b3fa18
@ -3208,7 +3208,10 @@ static int qgroup_snapshot_quick_inherit(struct btrfs_fs_info *fs_info,
|
||||
{
|
||||
struct btrfs_qgroup *src;
|
||||
struct btrfs_qgroup *parent;
|
||||
struct btrfs_qgroup *qgroup;
|
||||
struct btrfs_qgroup_list *list;
|
||||
LIST_HEAD(qgroup_list);
|
||||
const u32 nodesize = fs_info->nodesize;
|
||||
int nr_parents = 0;
|
||||
|
||||
if (btrfs_qgroup_mode(fs_info) != BTRFS_QGROUP_MODE_FULL)
|
||||
@ -3248,8 +3251,19 @@ static int qgroup_snapshot_quick_inherit(struct btrfs_fs_info *fs_info,
|
||||
if (parent->excl != parent->rfer)
|
||||
return 1;
|
||||
|
||||
parent->excl += fs_info->nodesize;
|
||||
parent->rfer += fs_info->nodesize;
|
||||
qgroup_iterator_add(&qgroup_list, parent);
|
||||
list_for_each_entry(qgroup, &qgroup_list, iterator) {
|
||||
qgroup->rfer += nodesize;
|
||||
qgroup->rfer_cmpr += nodesize;
|
||||
qgroup->excl += nodesize;
|
||||
qgroup->excl_cmpr += nodesize;
|
||||
qgroup_dirty(fs_info, qgroup);
|
||||
|
||||
/* Append parent qgroups to @qgroup_list. */
|
||||
list_for_each_entry(list, &qgroup->groups, next_group)
|
||||
qgroup_iterator_add(&qgroup_list, list->group);
|
||||
}
|
||||
qgroup_iterator_clean(&qgroup_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user