btrfs: extent-tree: Use btrfs_ref to refactor btrfs_inc_extent_ref()
Use the new btrfs_ref structure and replace parameter list to clean up the usage of owner and level to distinguish the extent types. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ddf30cf03f
commit
82fa113fcc
|
@ -41,6 +41,7 @@ extern struct kmem_cache *btrfs_bit_radix_cachep;
|
|||
extern struct kmem_cache *btrfs_path_cachep;
|
||||
extern struct kmem_cache *btrfs_free_space_cachep;
|
||||
struct btrfs_ordered_sum;
|
||||
struct btrfs_ref;
|
||||
|
||||
#define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */
|
||||
|
||||
|
@ -2760,9 +2761,7 @@ int btrfs_free_and_pin_reserved_extent(struct btrfs_fs_info *fs_info,
|
|||
void btrfs_prepare_extent_commit(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans);
|
||||
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 bytenr, u64 num_bytes, u64 parent,
|
||||
u64 root_objectid, u64 owner, u64 offset);
|
||||
struct btrfs_ref *generic_ref);
|
||||
|
||||
int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans);
|
||||
int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans);
|
||||
|
|
|
@ -2043,35 +2043,28 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
|
|||
|
||||
/* Can return -ENOMEM */
|
||||
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 bytenr, u64 num_bytes, u64 parent,
|
||||
u64 root_objectid, u64 owner, u64 offset)
|
||||
struct btrfs_ref *generic_ref)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_ref generic_ref = { 0 };
|
||||
struct btrfs_fs_info *fs_info = trans->fs_info;
|
||||
int old_ref_mod, new_ref_mod;
|
||||
int ret;
|
||||
|
||||
BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID &&
|
||||
root_objectid == BTRFS_TREE_LOG_OBJECTID);
|
||||
ASSERT(generic_ref->type != BTRFS_REF_NOT_SET &&
|
||||
generic_ref->action);
|
||||
BUG_ON(generic_ref->type == BTRFS_REF_METADATA &&
|
||||
generic_ref->tree_ref.root == BTRFS_TREE_LOG_OBJECTID);
|
||||
|
||||
btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_REF, bytenr,
|
||||
num_bytes, parent);
|
||||
generic_ref.real_root = root->root_key.objectid;
|
||||
if (owner < BTRFS_FIRST_FREE_OBJECTID) {
|
||||
btrfs_init_tree_ref(&generic_ref, (int)owner, root_objectid);
|
||||
ret = btrfs_add_delayed_tree_ref(trans, &generic_ref,
|
||||
if (generic_ref->type == BTRFS_REF_METADATA)
|
||||
ret = btrfs_add_delayed_tree_ref(trans, generic_ref,
|
||||
NULL, &old_ref_mod, &new_ref_mod);
|
||||
} else {
|
||||
btrfs_init_data_ref(&generic_ref, root_objectid, owner, offset);
|
||||
ret = btrfs_add_delayed_data_ref(trans, &generic_ref, 0,
|
||||
else
|
||||
ret = btrfs_add_delayed_data_ref(trans, generic_ref, 0,
|
||||
&old_ref_mod, &new_ref_mod);
|
||||
}
|
||||
|
||||
btrfs_ref_tree_mod(fs_info, &generic_ref);
|
||||
btrfs_ref_tree_mod(fs_info, generic_ref);
|
||||
|
||||
if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0)
|
||||
add_pinned_bytes(fs_info, &generic_ref);
|
||||
add_pinned_bytes(fs_info, generic_ref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -3151,7 +3144,10 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
|
|||
u32 nritems;
|
||||
struct btrfs_key key;
|
||||
struct btrfs_file_extent_item *fi;
|
||||
struct btrfs_ref generic_ref = { 0 };
|
||||
bool for_reloc = btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC);
|
||||
int i;
|
||||
int action;
|
||||
int level;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -3169,6 +3165,10 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
|
|||
parent = buf->start;
|
||||
else
|
||||
parent = 0;
|
||||
if (inc)
|
||||
action = BTRFS_ADD_DELAYED_REF;
|
||||
else
|
||||
action = BTRFS_DROP_DELAYED_REF;
|
||||
|
||||
for (i = 0; i < nritems; i++) {
|
||||
if (level == 0) {
|
||||
|
@ -3186,10 +3186,14 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
|
|||
|
||||
num_bytes = btrfs_file_extent_disk_num_bytes(buf, fi);
|
||||
key.offset -= btrfs_file_extent_offset(buf, fi);
|
||||
btrfs_init_generic_ref(&generic_ref, action, bytenr,
|
||||
num_bytes, parent);
|
||||
generic_ref.real_root = root->root_key.objectid;
|
||||
btrfs_init_data_ref(&generic_ref, ref_root, key.objectid,
|
||||
key.offset);
|
||||
generic_ref.skip_qgroup = for_reloc;
|
||||
if (inc)
|
||||
ret = btrfs_inc_extent_ref(trans, root, bytenr,
|
||||
num_bytes, parent, ref_root,
|
||||
key.objectid, key.offset);
|
||||
ret = btrfs_inc_extent_ref(trans, &generic_ref);
|
||||
else
|
||||
ret = btrfs_free_extent(trans, root, bytenr,
|
||||
num_bytes, parent, ref_root,
|
||||
|
@ -3199,10 +3203,13 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
|
|||
} else {
|
||||
bytenr = btrfs_node_blockptr(buf, i);
|
||||
num_bytes = fs_info->nodesize;
|
||||
btrfs_init_generic_ref(&generic_ref, action, bytenr,
|
||||
num_bytes, parent);
|
||||
generic_ref.real_root = root->root_key.objectid;
|
||||
btrfs_init_tree_ref(&generic_ref, level - 1, ref_root);
|
||||
generic_ref.skip_qgroup = for_reloc;
|
||||
if (inc)
|
||||
ret = btrfs_inc_extent_ref(trans, root, bytenr,
|
||||
num_bytes, parent, ref_root,
|
||||
level - 1, 0);
|
||||
ret = btrfs_inc_extent_ref(trans, &generic_ref);
|
||||
else
|
||||
ret = btrfs_free_extent(trans, root, bytenr,
|
||||
num_bytes, parent, ref_root,
|
||||
|
|
|
@ -754,6 +754,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct extent_buffer *leaf;
|
||||
struct btrfs_file_extent_item *fi;
|
||||
struct btrfs_ref ref = { 0 };
|
||||
struct btrfs_key key;
|
||||
struct btrfs_key new_key;
|
||||
u64 ino = btrfs_ino(BTRFS_I(inode));
|
||||
|
@ -909,11 +910,14 @@ next_slot:
|
|||
btrfs_mark_buffer_dirty(leaf);
|
||||
|
||||
if (update_refs && disk_bytenr > 0) {
|
||||
ret = btrfs_inc_extent_ref(trans, root,
|
||||
disk_bytenr, num_bytes, 0,
|
||||
btrfs_init_generic_ref(&ref,
|
||||
BTRFS_ADD_DELAYED_REF,
|
||||
disk_bytenr, num_bytes, 0);
|
||||
btrfs_init_data_ref(&ref,
|
||||
root->root_key.objectid,
|
||||
new_key.objectid,
|
||||
start - extent_offset);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
}
|
||||
key.offset = start;
|
||||
|
@ -1142,6 +1146,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
|
|||
struct extent_buffer *leaf;
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_file_extent_item *fi;
|
||||
struct btrfs_ref ref = { 0 };
|
||||
struct btrfs_key key;
|
||||
struct btrfs_key new_key;
|
||||
u64 bytenr;
|
||||
|
@ -1287,9 +1292,11 @@ again:
|
|||
extent_end - split);
|
||||
btrfs_mark_buffer_dirty(leaf);
|
||||
|
||||
ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes,
|
||||
0, root->root_key.objectid,
|
||||
ino, orig_offset);
|
||||
btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, bytenr,
|
||||
num_bytes, 0);
|
||||
btrfs_init_data_ref(&ref, root->root_key.objectid, ino,
|
||||
orig_offset);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
|
|
|
@ -2519,6 +2519,7 @@ static noinline int relink_extent_backref(struct btrfs_path *path,
|
|||
struct btrfs_file_extent_item *item;
|
||||
struct btrfs_ordered_extent *ordered;
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_ref ref = { 0 };
|
||||
struct btrfs_root *root;
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *leaf;
|
||||
|
@ -2689,10 +2690,11 @@ again:
|
|||
inode_add_bytes(inode, len);
|
||||
btrfs_release_path(path);
|
||||
|
||||
ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
|
||||
new->disk_len, 0,
|
||||
backref->root_id, backref->inum,
|
||||
new->file_pos); /* start - extent_offset */
|
||||
btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new->bytenr,
|
||||
new->disk_len, 0);
|
||||
btrfs_init_data_ref(&ref, backref->root_id, backref->inum,
|
||||
new->file_pos); /* start - extent_offset */
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out_free_path;
|
||||
|
|
|
@ -3737,13 +3737,16 @@ process_slot:
|
|||
datal);
|
||||
|
||||
if (disko) {
|
||||
struct btrfs_ref ref = { 0 };
|
||||
inode_add_bytes(inode, datal);
|
||||
ret = btrfs_inc_extent_ref(trans,
|
||||
root,
|
||||
disko, diskl, 0,
|
||||
root->root_key.objectid,
|
||||
btrfs_ino(BTRFS_I(inode)),
|
||||
new_key.offset - datao);
|
||||
btrfs_init_generic_ref(&ref,
|
||||
BTRFS_ADD_DELAYED_REF, disko,
|
||||
diskl, 0);
|
||||
btrfs_init_data_ref(&ref,
|
||||
root->root_key.objectid,
|
||||
btrfs_ino(BTRFS_I(inode)),
|
||||
new_key.offset - datao);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans,
|
||||
ret);
|
||||
|
|
|
@ -1643,6 +1643,8 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
|
|||
|
||||
nritems = btrfs_header_nritems(leaf);
|
||||
for (i = 0; i < nritems; i++) {
|
||||
struct btrfs_ref ref = { 0 };
|
||||
|
||||
cond_resched();
|
||||
btrfs_item_key_to_cpu(leaf, &key, i);
|
||||
if (key.type != BTRFS_EXTENT_DATA_KEY)
|
||||
|
@ -1703,10 +1705,12 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
|
|||
dirty = 1;
|
||||
|
||||
key.offset -= btrfs_file_extent_offset(leaf, fi);
|
||||
ret = btrfs_inc_extent_ref(trans, root, new_bytenr,
|
||||
num_bytes, parent,
|
||||
btrfs_header_owner(leaf),
|
||||
key.objectid, key.offset);
|
||||
btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
|
||||
num_bytes, parent);
|
||||
ref.real_root = root->root_key.objectid;
|
||||
btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
|
||||
key.objectid, key.offset);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
break;
|
||||
|
@ -1756,6 +1760,7 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
|
|||
struct btrfs_fs_info *fs_info = dest->fs_info;
|
||||
struct extent_buffer *eb;
|
||||
struct extent_buffer *parent;
|
||||
struct btrfs_ref ref = { 0 };
|
||||
struct btrfs_key key;
|
||||
u64 old_bytenr;
|
||||
u64 new_bytenr;
|
||||
|
@ -1916,13 +1921,17 @@ again:
|
|||
path->slots[level], old_ptr_gen);
|
||||
btrfs_mark_buffer_dirty(path->nodes[level]);
|
||||
|
||||
ret = btrfs_inc_extent_ref(trans, src, old_bytenr,
|
||||
blocksize, path->nodes[level]->start,
|
||||
src->root_key.objectid, level - 1, 0);
|
||||
btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, old_bytenr,
|
||||
blocksize, path->nodes[level]->start);
|
||||
ref.skip_qgroup = true;
|
||||
btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
BUG_ON(ret);
|
||||
ret = btrfs_inc_extent_ref(trans, dest, new_bytenr,
|
||||
blocksize, 0, dest->root_key.objectid,
|
||||
level - 1, 0);
|
||||
btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
|
||||
blocksize, 0);
|
||||
ref.skip_qgroup = true;
|
||||
btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
BUG_ON(ret);
|
||||
|
||||
ret = btrfs_free_extent(trans, src, new_bytenr, blocksize,
|
||||
|
@ -2721,6 +2730,7 @@ static int do_relocation(struct btrfs_trans_handle *trans,
|
|||
rc->backref_cache.path[node->level] = node;
|
||||
list_for_each_entry(edge, &node->upper, list[LOWER]) {
|
||||
struct btrfs_key first_key;
|
||||
struct btrfs_ref ref = { 0 };
|
||||
|
||||
cond_resched();
|
||||
|
||||
|
@ -2826,11 +2836,13 @@ static int do_relocation(struct btrfs_trans_handle *trans,
|
|||
trans->transid);
|
||||
btrfs_mark_buffer_dirty(upper->eb);
|
||||
|
||||
ret = btrfs_inc_extent_ref(trans, root,
|
||||
node->eb->start, blocksize,
|
||||
upper->eb->start,
|
||||
btrfs_header_owner(upper->eb),
|
||||
node->level, 0);
|
||||
btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF,
|
||||
node->eb->start, blocksize,
|
||||
upper->eb->start);
|
||||
ref.real_root = root->root_key.objectid;
|
||||
btrfs_init_tree_ref(&ref, node->level,
|
||||
btrfs_header_owner(upper->eb));
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
BUG_ON(ret);
|
||||
|
||||
ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
|
||||
|
|
|
@ -705,9 +705,11 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
|
|||
goto out;
|
||||
|
||||
if (ins.objectid > 0) {
|
||||
struct btrfs_ref ref = { 0 };
|
||||
u64 csum_start;
|
||||
u64 csum_end;
|
||||
LIST_HEAD(ordered_sums);
|
||||
|
||||
/*
|
||||
* is this extent already allocated in the extent
|
||||
* allocation tree? If so, just add a reference
|
||||
|
@ -715,10 +717,13 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
|
|||
ret = btrfs_lookup_data_extent(fs_info, ins.objectid,
|
||||
ins.offset);
|
||||
if (ret == 0) {
|
||||
ret = btrfs_inc_extent_ref(trans, root,
|
||||
ins.objectid, ins.offset,
|
||||
0, root->root_key.objectid,
|
||||
btrfs_init_generic_ref(&ref,
|
||||
BTRFS_ADD_DELAYED_REF,
|
||||
ins.objectid, ins.offset, 0);
|
||||
btrfs_init_data_ref(&ref,
|
||||
root->root_key.objectid,
|
||||
key->objectid, offset);
|
||||
ret = btrfs_inc_extent_ref(trans, &ref);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue