mirror of
https://github.com/kdave/btrfs-progs
synced 2025-01-20 12:40:50 +00:00
btrfs-progs: add btrfs_clear_free_space_tree() from the kernel
Reviewed-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
441d8aea8f
commit
9814411021
6
ctree.h
6
ctree.h
@ -2504,6 +2504,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|||||||
struct extent_buffer *buf, int record_parent);
|
struct extent_buffer *buf, int record_parent);
|
||||||
int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||||
struct extent_buffer *buf, int record_parent);
|
struct extent_buffer *buf, int record_parent);
|
||||||
|
int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_root *root,
|
||||||
|
struct extent_buffer *buf,
|
||||||
|
u64 parent, int last_ref);
|
||||||
int btrfs_free_extent(struct btrfs_trans_handle *trans,
|
int btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root,
|
struct btrfs_root *root,
|
||||||
u64 bytenr, u64 num_bytes, u64 parent,
|
u64 bytenr, u64 num_bytes, u64 parent,
|
||||||
@ -2664,6 +2668,8 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
|
|||||||
int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
|
int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||||
*root, struct btrfs_key *key, struct btrfs_root_item
|
*root, struct btrfs_key *key, struct btrfs_root_item
|
||||||
*item);
|
*item);
|
||||||
|
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||||
|
struct btrfs_key *key);
|
||||||
int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
|
int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||||
*root, struct btrfs_key *key, struct btrfs_root_item
|
*root, struct btrfs_key *key, struct btrfs_root_item
|
||||||
*item);
|
*item);
|
||||||
|
@ -2467,6 +2467,17 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_root *root,
|
||||||
|
struct extent_buffer *buf,
|
||||||
|
u64 parent, int last_ref)
|
||||||
|
{
|
||||||
|
return btrfs_free_extent(trans, root, buf->start, buf->len, parent,
|
||||||
|
root->root_key.objectid,
|
||||||
|
btrfs_header_level(buf), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove an extent from the root, returns 0 on success
|
* remove an extent from the root, returns 0 on success
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "disk-io.h"
|
#include "disk-io.h"
|
||||||
#include "free-space-cache.h"
|
#include "free-space-cache.h"
|
||||||
#include "free-space-tree.h"
|
#include "free-space-tree.h"
|
||||||
|
#include "transaction.h"
|
||||||
|
|
||||||
static struct btrfs_free_space_info *
|
static struct btrfs_free_space_info *
|
||||||
search_free_space_info(struct btrfs_trans_handle *trans,
|
search_free_space_info(struct btrfs_trans_handle *trans,
|
||||||
@ -67,6 +68,91 @@ static int free_space_test_bit(struct btrfs_block_group_cache *block_group,
|
|||||||
return !!extent_buffer_test_bit(leaf, ptr, i);
|
return !!extent_buffer_test_bit(leaf, ptr, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int clear_free_space_tree(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_root *root)
|
||||||
|
{
|
||||||
|
struct btrfs_path *path;
|
||||||
|
struct btrfs_key key;
|
||||||
|
int nr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
path = btrfs_alloc_path();
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
key.objectid = 0;
|
||||||
|
key.type = 0;
|
||||||
|
key.offset = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
nr = btrfs_header_nritems(path->nodes[0]);
|
||||||
|
if (!nr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
path->slots[0] = 0;
|
||||||
|
ret = btrfs_del_items(trans, root, path, 0, nr);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
btrfs_release_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
btrfs_free_path(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||||
|
{
|
||||||
|
struct btrfs_trans_handle *trans;
|
||||||
|
struct btrfs_root *tree_root = fs_info->tree_root;
|
||||||
|
struct btrfs_root *free_space_root = fs_info->free_space_root;
|
||||||
|
int ret;
|
||||||
|
u64 features;
|
||||||
|
|
||||||
|
trans = btrfs_start_transaction(tree_root, 0);
|
||||||
|
if (IS_ERR(trans))
|
||||||
|
return PTR_ERR(trans);
|
||||||
|
|
||||||
|
features = btrfs_super_compat_ro_flags(fs_info->super_copy);
|
||||||
|
features &= ~(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID |
|
||||||
|
BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE);
|
||||||
|
btrfs_set_super_compat_ro_flags(fs_info->super_copy, features);
|
||||||
|
fs_info->free_space_root = NULL;
|
||||||
|
|
||||||
|
ret = clear_free_space_tree(trans, free_space_root);
|
||||||
|
if (ret)
|
||||||
|
goto abort;
|
||||||
|
|
||||||
|
ret = btrfs_del_root(trans, tree_root, &free_space_root->root_key);
|
||||||
|
if (ret)
|
||||||
|
goto abort;
|
||||||
|
|
||||||
|
list_del(&free_space_root->dirty_list);
|
||||||
|
|
||||||
|
ret = clean_tree_block(trans, tree_root, free_space_root->node);
|
||||||
|
if (ret)
|
||||||
|
goto abort;
|
||||||
|
ret = btrfs_free_tree_block(trans, free_space_root,
|
||||||
|
free_space_root->node, 0, 1);
|
||||||
|
if (ret)
|
||||||
|
goto abort;
|
||||||
|
|
||||||
|
free_extent_buffer(free_space_root->node);
|
||||||
|
free_extent_buffer(free_space_root->commit_root);
|
||||||
|
kfree(free_space_root);
|
||||||
|
|
||||||
|
ret = btrfs_commit_transaction(trans, tree_root);
|
||||||
|
|
||||||
|
abort:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int load_free_space_bitmaps(struct btrfs_fs_info *fs_info,
|
static int load_free_space_bitmaps(struct btrfs_fs_info *fs_info,
|
||||||
struct btrfs_block_group_cache *block_group,
|
struct btrfs_block_group_cache *block_group,
|
||||||
struct btrfs_path *path,
|
struct btrfs_path *path,
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#ifndef __BTRFS_FREE_SPACE_TREE_H__
|
#ifndef __BTRFS_FREE_SPACE_TREE_H__
|
||||||
#define __BTRFS_FREE_SPACE_TREE_H__
|
#define __BTRFS_FREE_SPACE_TREE_H__
|
||||||
|
|
||||||
|
int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info);
|
||||||
int load_free_space_tree(struct btrfs_fs_info *fs_info,
|
int load_free_space_tree(struct btrfs_fs_info *fs_info,
|
||||||
struct btrfs_block_group_cache *block_group);
|
struct btrfs_block_group_cache *block_group);
|
||||||
|
|
||||||
|
25
root-tree.c
25
root-tree.c
@ -143,6 +143,31 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* drop the root item for 'key' from 'root' */
|
||||||
|
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||||
|
struct btrfs_key *key)
|
||||||
|
{
|
||||||
|
struct btrfs_path *path;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
path = btrfs_alloc_path();
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
ret = btrfs_search_slot(trans, root, key, path, -1, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = btrfs_del_item(trans, root, path);
|
||||||
|
out:
|
||||||
|
btrfs_free_path(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY
|
* add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY
|
||||||
* or BTRFS_ROOT_BACKREF_KEY.
|
* or BTRFS_ROOT_BACKREF_KEY.
|
||||||
|
Loading…
Reference in New Issue
Block a user