Skip to content

Commit 839d6ea

Browse files
adam900710kdave
authored andcommitted
btrfs: automatically remove the subvolume qgroup
Currently if we fully clean a subvolume (not only delete its directory, but fully clean all it's related data and root item), the associated qgroup would not be removed. We have "btrfs qgroup clear-stale" to handle such 0 level qgroups. Change the behavior to automatically removie the qgroup of a fully cleaned subvolume when possible: - Full qgroup but still consistent We can and should remove the qgroup. The qgroup numbers should be 0, without any rsv. - Full qgroup but inconsistent Can happen with drop_subtree_threshold feature (skip accounting and mark qgroup inconsistent). We can and should remove the qgroup. Higher level qgroup numbers will be incorrect, but since qgroup is already inconsistent, it should not be a problem. - Squota mode This is the special case, we can only drop the qgroup if its numbers are all 0. This would be handled by can_delete_qgroup(), so we only need to check the return value and ignore the -EBUSY error. Link: https://bugzilla.suse.com/show_bug.cgi?id=1222847 Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent a776bf5 commit 839d6ea

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

fs/btrfs/extent-tree.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,6 +5833,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
58335833
struct btrfs_root_item *root_item = &root->root_item;
58345834
struct walk_control *wc;
58355835
struct btrfs_key key;
5836+
const u64 rootid = btrfs_root_id(root);
58365837
int err = 0;
58375838
int ret;
58385839
int level;
@@ -6063,6 +6064,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
60636064
kfree(wc);
60646065
btrfs_free_path(path);
60656066
out:
6067+
if (!err && root_dropped) {
6068+
ret = btrfs_qgroup_cleanup_dropped_subvolume(fs_info, rootid);
6069+
if (ret < 0)
6070+
btrfs_warn_rl(fs_info,
6071+
"failed to cleanup qgroup 0/%llu: %d",
6072+
rootid, ret);
6073+
}
60666074
/*
60676075
* We were an unfinished drop root, check to see if there are any
60686076
* pending, and if not clear and wake up any waiters.

fs/btrfs/qgroup.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,41 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
18891889
return ret;
18901890
}
18911891

1892+
int btrfs_qgroup_cleanup_dropped_subvolume(struct btrfs_fs_info *fs_info, u64 subvolid)
1893+
{
1894+
struct btrfs_trans_handle *trans;
1895+
int ret;
1896+
1897+
if (!is_fstree(subvolid) || !btrfs_qgroup_enabled(fs_info) || !fs_info->quota_root)
1898+
return 0;
1899+
1900+
/*
1901+
* Commit current transaction to make sure all the rfer/excl numbers
1902+
* get updated.
1903+
*/
1904+
trans = btrfs_start_transaction(fs_info->quota_root, 0);
1905+
if (IS_ERR(trans))
1906+
return PTR_ERR(trans);
1907+
1908+
ret = btrfs_commit_transaction(trans);
1909+
if (ret < 0)
1910+
return ret;
1911+
1912+
/* Start new trans to delete the qgroup info and limit items. */
1913+
trans = btrfs_start_transaction(fs_info->quota_root, 2);
1914+
if (IS_ERR(trans))
1915+
return PTR_ERR(trans);
1916+
ret = btrfs_remove_qgroup(trans, subvolid);
1917+
btrfs_end_transaction(trans);
1918+
/*
1919+
* It's squota and the subvolume still has numbers needed for future
1920+
* accounting, in this case we can not delete it. Just skip it.
1921+
*/
1922+
if (ret == -EBUSY)
1923+
ret = 0;
1924+
return ret;
1925+
}
1926+
18921927
int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid,
18931928
struct btrfs_qgroup_limit *limit)
18941929
{

fs/btrfs/qgroup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
327327
u64 dst);
328328
int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid);
329329
int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid);
330+
int btrfs_qgroup_cleanup_dropped_subvolume(struct btrfs_fs_info *fs_info, u64 subvolid);
330331
int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid,
331332
struct btrfs_qgroup_limit *limit);
332333
int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info);

0 commit comments

Comments
 (0)