Skip to content

Commit 813e157

Browse files
boryasadam900710
authored andcommitted
btrfs-progs: add a helper for clearing all the items in a tree
Used in clear_free_space_tree, this is a totally generic operation. It will also be used for clearing the qgroup tree from btrfstune. Reviewed-by: Anand Jain <[email protected]> Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Boris Burkov <[email protected]> [ Make remove_all_tree_items() to use btrfs_clear_tree() ] Signed-off-by: Qu Wenruo <[email protected]>
1 parent 916e0f4 commit 813e157

File tree

4 files changed

+50
-76
lines changed

4 files changed

+50
-76
lines changed

common/root-tree-utils.c

+7-36
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,6 @@ int btrfs_link_subvolume(struct btrfs_trans_handle *trans,
226226
static int remove_all_tree_items(struct btrfs_root *root)
227227
{
228228
struct btrfs_trans_handle *trans;
229-
struct btrfs_path path = { 0 };
230-
struct btrfs_key key = { 0 };
231229
int ret;
232230

233231
trans = btrfs_start_transaction(root, 1);
@@ -239,40 +237,13 @@ static int remove_all_tree_items(struct btrfs_root *root)
239237
root->root_key.objectid);
240238
return ret;
241239
}
242-
while (true) {
243-
int nr_items;
244-
245-
ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
246-
if (ret < 0) {
247-
errno = -ret;
248-
error("failed to locate the first key of root %lld: %m",
249-
root->root_key.objectid);
250-
btrfs_abort_transaction(trans, ret);
251-
return ret;
252-
}
253-
if (ret == 0) {
254-
ret = -EUCLEAN;
255-
errno = -ret;
256-
error("unexpected all zero key found in root %lld",
257-
root->root_key.objectid);
258-
btrfs_abort_transaction(trans, ret);
259-
return ret;
260-
}
261-
nr_items = btrfs_header_nritems(path.nodes[0]);
262-
/* The tree is empty. */
263-
if (nr_items == 0) {
264-
btrfs_release_path(&path);
265-
break;
266-
}
267-
ret = btrfs_del_items(trans, root, &path, 0, nr_items);
268-
btrfs_release_path(&path);
269-
if (ret < 0) {
270-
errno = -ret;
271-
error("failed to empty the first leaf of root %lld: %m",
272-
root->root_key.objectid);
273-
btrfs_abort_transaction(trans, ret);
274-
return ret;
275-
}
240+
ret = btrfs_clear_tree(trans, root);
241+
if (ret < 0) {
242+
errno = -ret;
243+
error("failed to empty root %lld: %m",
244+
root->root_key.objectid);
245+
btrfs_abort_transaction(trans, ret);
246+
return ret;
276247
}
277248
ret = btrfs_commit_transaction(trans, root);
278249
if (ret < 0) {

kernel-shared/disk-io.c

+39
Original file line numberDiff line numberDiff line change
@@ -2342,6 +2342,45 @@ static bool is_global_root(struct btrfs_root *root)
23422342
return true;
23432343
return false;
23442344
}
2345+
2346+
int btrfs_clear_tree(struct btrfs_trans_handle *trans,
2347+
struct btrfs_root *root)
2348+
{
2349+
struct btrfs_path *path;
2350+
struct btrfs_key key;
2351+
struct extent_buffer *leaf = NULL;
2352+
int ret;
2353+
int nr = 0;
2354+
2355+
path = btrfs_alloc_path();
2356+
if (!path)
2357+
return -ENOMEM;
2358+
2359+
key.objectid = 0;
2360+
key.offset = 0;
2361+
key.type = 0;
2362+
2363+
while (1) {
2364+
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
2365+
if (ret < 0)
2366+
goto out;
2367+
leaf = path->nodes[0];
2368+
nr = btrfs_header_nritems(leaf);
2369+
if (!nr)
2370+
break;
2371+
path->slots[0] = 0;
2372+
ret = btrfs_del_items(trans, root, path, 0, nr);
2373+
if (ret)
2374+
goto out;
2375+
2376+
btrfs_release_path(path);
2377+
}
2378+
ret = 0;
2379+
out:
2380+
btrfs_free_path(path);
2381+
return ret;
2382+
}
2383+
23452384
int btrfs_delete_and_free_root(struct btrfs_trans_handle *trans,
23462385
struct btrfs_root *root)
23472386
{

kernel-shared/disk-io.h

+2
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ int write_tree_block(struct btrfs_trans_handle *trans,
240240
int btrfs_fs_roots_compare_roots(const struct rb_node *node1, const struct rb_node *node2);
241241
struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
242242
struct btrfs_key *key);
243+
int btrfs_clear_tree(struct btrfs_trans_handle *trans,
244+
struct btrfs_root *root);
243245
int btrfs_delete_and_free_root(struct btrfs_trans_handle *trans,
244246
struct btrfs_root *root);
245247
struct btrfs_root *btrfs_csum_root(struct btrfs_fs_info *fs_info, u64 bytenr);

kernel-shared/free-space-tree.c

+2-40
Original file line numberDiff line numberDiff line change
@@ -1228,44 +1228,6 @@ int remove_block_group_free_space(struct btrfs_trans_handle *trans,
12281228
btrfs_abort_transaction(trans, ret);
12291229
return ret;
12301230
}
1231-
static int clear_free_space_tree(struct btrfs_trans_handle *trans,
1232-
struct btrfs_root *root)
1233-
{
1234-
struct btrfs_path *path;
1235-
struct btrfs_key key;
1236-
int nr;
1237-
int ret;
1238-
1239-
path = btrfs_alloc_path();
1240-
if (!path)
1241-
return -ENOMEM;
1242-
1243-
key.objectid = 0;
1244-
key.type = 0;
1245-
key.offset = 0;
1246-
1247-
while (1) {
1248-
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
1249-
if (ret < 0)
1250-
goto out;
1251-
1252-
nr = btrfs_header_nritems(path->nodes[0]);
1253-
if (!nr)
1254-
break;
1255-
1256-
path->slots[0] = 0;
1257-
ret = btrfs_del_items(trans, root, path, 0, nr);
1258-
if (ret)
1259-
goto out;
1260-
1261-
btrfs_release_path(path);
1262-
}
1263-
1264-
ret = 0;
1265-
out:
1266-
btrfs_free_path(path);
1267-
return ret;
1268-
}
12691231

12701232
int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
12711233
{
@@ -1288,7 +1250,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
12881250

12891251
while (key.offset < fs_info->nr_global_roots) {
12901252
free_space_root = btrfs_global_root(fs_info, &key);
1291-
ret = clear_free_space_tree(trans, free_space_root);
1253+
ret = btrfs_clear_tree(trans, free_space_root);
12921254
if (ret)
12931255
goto abort;
12941256
key.offset++;
@@ -1299,7 +1261,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
12991261
BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE);
13001262
btrfs_set_super_compat_ro_flags(fs_info->super_copy, features);
13011263

1302-
ret = clear_free_space_tree(trans, free_space_root);
1264+
ret = btrfs_clear_tree(trans, free_space_root);
13031265
if (ret)
13041266
goto abort;
13051267

0 commit comments

Comments
 (0)