Commit 66d7e7f0 authored by Arne Jansen's avatar Arne Jansen Committed by Jan Schmidt

Btrfs: mark delayed refs as for cow

Add a for_cow parameter to add_delayed_*_ref and pass the appropriate value
from every call site. The for_cow parameter will later on be used to
determine if a ref will change anything with respect to qgroups.

Delayed refs coming from relocation are always counted as for_cow, as they
don't change subvol quota.

Also pass in the fs_info for later use.

btrfs_find_all_roots() will use this as an optimization, as changes that are
for_cow will not change anything with respect to which root points to a
certain leaf. Thus, we don't need to add the current sequence number to
those delayed refs.
Signed-off-by: default avatarArne Jansen <sensille@gmx.net>
Signed-off-by: default avatarJan Schmidt <list.btrfs@jan-o-sch.net>
parent c7d22a3c
...@@ -240,7 +240,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, ...@@ -240,7 +240,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
cow = btrfs_alloc_free_block(trans, root, buf->len, 0, cow = btrfs_alloc_free_block(trans, root, buf->len, 0,
new_root_objectid, &disk_key, level, new_root_objectid, &disk_key, level,
buf->start, 0); buf->start, 0, 1);
if (IS_ERR(cow)) if (IS_ERR(cow))
return PTR_ERR(cow); return PTR_ERR(cow);
...@@ -261,9 +261,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, ...@@ -261,9 +261,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
WARN_ON(btrfs_header_generation(buf) > trans->transid); WARN_ON(btrfs_header_generation(buf) > trans->transid);
if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID)
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1, 1);
else else
ret = btrfs_inc_ref(trans, root, cow, 0); ret = btrfs_inc_ref(trans, root, cow, 0, 1);
if (ret) if (ret)
return ret; return ret;
...@@ -350,14 +350,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -350,14 +350,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
if ((owner == root->root_key.objectid || if ((owner == root->root_key.objectid ||
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) &&
!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) {
ret = btrfs_inc_ref(trans, root, buf, 1); ret = btrfs_inc_ref(trans, root, buf, 1, 1);
BUG_ON(ret); BUG_ON(ret);
if (root->root_key.objectid == if (root->root_key.objectid ==
BTRFS_TREE_RELOC_OBJECTID) { BTRFS_TREE_RELOC_OBJECTID) {
ret = btrfs_dec_ref(trans, root, buf, 0); ret = btrfs_dec_ref(trans, root, buf, 0, 1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1, 1);
BUG_ON(ret); BUG_ON(ret);
} }
new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
...@@ -365,9 +365,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -365,9 +365,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
if (root->root_key.objectid == if (root->root_key.objectid ==
BTRFS_TREE_RELOC_OBJECTID) BTRFS_TREE_RELOC_OBJECTID)
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1, 1);
else else
ret = btrfs_inc_ref(trans, root, cow, 0); ret = btrfs_inc_ref(trans, root, cow, 0, 1);
BUG_ON(ret); BUG_ON(ret);
} }
if (new_flags != 0) { if (new_flags != 0) {
...@@ -381,11 +381,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -381,11 +381,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
if (root->root_key.objectid == if (root->root_key.objectid ==
BTRFS_TREE_RELOC_OBJECTID) BTRFS_TREE_RELOC_OBJECTID)
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1, 1);
else else
ret = btrfs_inc_ref(trans, root, cow, 0); ret = btrfs_inc_ref(trans, root, cow, 0, 1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_dec_ref(trans, root, buf, 1); ret = btrfs_dec_ref(trans, root, buf, 1, 1);
BUG_ON(ret); BUG_ON(ret);
} }
clean_tree_block(trans, root, buf); clean_tree_block(trans, root, buf);
...@@ -446,7 +446,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -446,7 +446,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start,
root->root_key.objectid, &disk_key, root->root_key.objectid, &disk_key,
level, search_start, empty_size); level, search_start, empty_size, 1);
if (IS_ERR(cow)) if (IS_ERR(cow))
return PTR_ERR(cow); return PTR_ERR(cow);
...@@ -484,7 +484,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -484,7 +484,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
rcu_assign_pointer(root->node, cow); rcu_assign_pointer(root->node, cow);
btrfs_free_tree_block(trans, root, buf, parent_start, btrfs_free_tree_block(trans, root, buf, parent_start,
last_ref); last_ref, 1);
free_extent_buffer(buf); free_extent_buffer(buf);
add_root_to_dirty_list(root); add_root_to_dirty_list(root);
} else { } else {
...@@ -500,7 +500,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -500,7 +500,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
trans->transid); trans->transid);
btrfs_mark_buffer_dirty(parent); btrfs_mark_buffer_dirty(parent);
btrfs_free_tree_block(trans, root, buf, parent_start, btrfs_free_tree_block(trans, root, buf, parent_start,
last_ref); last_ref, 1);
} }
if (unlock_orig) if (unlock_orig)
btrfs_tree_unlock(buf); btrfs_tree_unlock(buf);
...@@ -957,7 +957,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -957,7 +957,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
free_extent_buffer(mid); free_extent_buffer(mid);
root_sub_used(root, mid->len); root_sub_used(root, mid->len);
btrfs_free_tree_block(trans, root, mid, 0, 1); btrfs_free_tree_block(trans, root, mid, 0, 1, 0);
/* once for the root ptr */ /* once for the root ptr */
free_extent_buffer(mid); free_extent_buffer(mid);
return 0; return 0;
...@@ -1015,7 +1015,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1015,7 +1015,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
if (wret) if (wret)
ret = wret; ret = wret;
root_sub_used(root, right->len); root_sub_used(root, right->len);
btrfs_free_tree_block(trans, root, right, 0, 1); btrfs_free_tree_block(trans, root, right, 0, 1, 0);
free_extent_buffer(right); free_extent_buffer(right);
right = NULL; right = NULL;
} else { } else {
...@@ -1055,7 +1055,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1055,7 +1055,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
if (wret) if (wret)
ret = wret; ret = wret;
root_sub_used(root, mid->len); root_sub_used(root, mid->len);
btrfs_free_tree_block(trans, root, mid, 0, 1); btrfs_free_tree_block(trans, root, mid, 0, 1, 0);
free_extent_buffer(mid); free_extent_buffer(mid);
mid = NULL; mid = NULL;
} else { } else {
...@@ -2089,7 +2089,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, ...@@ -2089,7 +2089,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, c = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
root->root_key.objectid, &lower_key, root->root_key.objectid, &lower_key,
level, root->node->start, 0); level, root->node->start, 0, 0);
if (IS_ERR(c)) if (IS_ERR(c))
return PTR_ERR(c); return PTR_ERR(c);
...@@ -2216,7 +2216,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, ...@@ -2216,7 +2216,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
split = btrfs_alloc_free_block(trans, root, root->nodesize, 0, split = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
root->root_key.objectid, root->root_key.objectid,
&disk_key, level, c->start, 0); &disk_key, level, c->start, 0, 0);
if (IS_ERR(split)) if (IS_ERR(split))
return PTR_ERR(split); return PTR_ERR(split);
...@@ -2970,7 +2970,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, ...@@ -2970,7 +2970,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
right = btrfs_alloc_free_block(trans, root, root->leafsize, 0, right = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
root->root_key.objectid, root->root_key.objectid,
&disk_key, 0, l->start, 0); &disk_key, 0, l->start, 0, 0);
if (IS_ERR(right)) if (IS_ERR(right))
return PTR_ERR(right); return PTR_ERR(right);
...@@ -3781,7 +3781,7 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, ...@@ -3781,7 +3781,7 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
root_sub_used(root, leaf->len); root_sub_used(root, leaf->len);
btrfs_free_tree_block(trans, root, leaf, 0, 1); btrfs_free_tree_block(trans, root, leaf, 0, 1, 0);
return 0; return 0;
} }
/* /*
......
...@@ -2277,11 +2277,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, ...@@ -2277,11 +2277,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u32 blocksize, struct btrfs_root *root, u32 blocksize,
u64 parent, u64 root_objectid, u64 parent, u64 root_objectid,
struct btrfs_disk_key *key, int level, struct btrfs_disk_key *key, int level,
u64 hint, u64 empty_size); u64 hint, u64 empty_size, int for_cow);
void btrfs_free_tree_block(struct btrfs_trans_handle *trans, void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *buf, struct extent_buffer *buf,
u64 parent, int last_ref); u64 parent, int last_ref, int for_cow);
struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
u64 bytenr, u32 blocksize, u64 bytenr, u32 blocksize,
...@@ -2301,17 +2301,17 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, ...@@ -2301,17 +2301,17 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
u64 search_end, struct btrfs_key *ins, u64 search_end, struct btrfs_key *ins,
u64 data); u64 data);
int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct extent_buffer *buf, int full_backref); struct extent_buffer *buf, int full_backref, int for_cow);
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 full_backref); struct extent_buffer *buf, int full_backref, int for_cow);
int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
u64 bytenr, u64 num_bytes, u64 flags, u64 bytenr, u64 num_bytes, u64 flags,
int is_data); int is_data);
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, u64 root_objectid,
u64 root_objectid, u64 owner, u64 offset); u64 owner, u64 offset, int for_cow);
int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len);
int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root,
...@@ -2323,7 +2323,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, ...@@ -2323,7 +2323,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, int btrfs_inc_extent_ref(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,
u64 root_objectid, u64 owner, u64 offset); u64 root_objectid, u64 owner, u64 offset, int for_cow);
int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root); struct btrfs_root *root);
...@@ -2492,7 +2492,8 @@ static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) ...@@ -2492,7 +2492,8 @@ static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p)
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
void btrfs_drop_snapshot(struct btrfs_root *root, void btrfs_drop_snapshot(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv, int update_ref); struct btrfs_block_rsv *block_rsv, int update_ref,
int for_reloc);
int btrfs_drop_subtree(struct btrfs_trans_handle *trans, int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *node, struct extent_buffer *node,
......
...@@ -390,7 +390,8 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing, ...@@ -390,7 +390,8 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing,
* this does all the dirty work in terms of maintaining the correct * this does all the dirty work in terms of maintaining the correct
* overall modification count. * overall modification count.
*/ */
static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
struct btrfs_delayed_ref_node *ref, struct btrfs_delayed_ref_node *ref,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
int action, int is_data) int action, int is_data)
...@@ -468,10 +469,12 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, ...@@ -468,10 +469,12 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans,
/* /*
* helper to insert a delayed tree ref into the rbtree. * helper to insert a delayed tree ref into the rbtree.
*/ */
static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
struct btrfs_delayed_ref_node *ref, struct btrfs_delayed_ref_node *ref,
u64 bytenr, u64 num_bytes, u64 parent, u64 bytenr, u64 num_bytes, u64 parent,
u64 ref_root, int level, int action) u64 ref_root, int level, int action,
int for_cow)
{ {
struct btrfs_delayed_ref_node *existing; struct btrfs_delayed_ref_node *existing;
struct btrfs_delayed_tree_ref *full_ref; struct btrfs_delayed_tree_ref *full_ref;
...@@ -522,11 +525,12 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, ...@@ -522,11 +525,12 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans,
/* /*
* helper to insert a delayed data ref into the rbtree. * helper to insert a delayed data ref into the rbtree.
*/ */
static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
struct btrfs_delayed_ref_node *ref, struct btrfs_delayed_ref_node *ref,
u64 bytenr, u64 num_bytes, u64 parent, u64 bytenr, u64 num_bytes, u64 parent,
u64 ref_root, u64 owner, u64 offset, u64 ref_root, u64 owner, u64 offset,
int action) int action, int for_cow)
{ {
struct btrfs_delayed_ref_node *existing; struct btrfs_delayed_ref_node *existing;
struct btrfs_delayed_data_ref *full_ref; struct btrfs_delayed_data_ref *full_ref;
...@@ -554,6 +558,7 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, ...@@ -554,6 +558,7 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans,
full_ref->root = ref_root; full_ref->root = ref_root;
ref->type = BTRFS_EXTENT_DATA_REF_KEY; ref->type = BTRFS_EXTENT_DATA_REF_KEY;
} }
full_ref->objectid = owner; full_ref->objectid = owner;
full_ref->offset = offset; full_ref->offset = offset;
...@@ -580,10 +585,12 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, ...@@ -580,10 +585,12 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans,
* to make sure the delayed ref is eventually processed before this * to make sure the delayed ref is eventually processed before this
* transaction commits. * transaction commits.
*/ */
int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 parent, u64 bytenr, u64 num_bytes, u64 parent,
u64 ref_root, int level, int action, u64 ref_root, int level, int action,
struct btrfs_delayed_extent_op *extent_op) struct btrfs_delayed_extent_op *extent_op,
int for_cow)
{ {
struct btrfs_delayed_tree_ref *ref; struct btrfs_delayed_tree_ref *ref;
struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_head *head_ref;
...@@ -610,12 +617,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, ...@@ -610,12 +617,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
* insert both the head node and the new ref without dropping * insert both the head node and the new ref without dropping
* the spin lock * the spin lock
*/ */
ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, num_bytes, ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr,
action, 0); num_bytes, action, 0);
BUG_ON(ret); BUG_ON(ret);
ret = add_delayed_tree_ref(trans, &ref->node, bytenr, num_bytes, ret = add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr,
parent, ref_root, level, action); num_bytes, parent, ref_root, level, action,
for_cow);
BUG_ON(ret); BUG_ON(ret);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
return 0; return 0;
...@@ -624,11 +632,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, ...@@ -624,11 +632,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
/* /*
* add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref. * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref.
*/ */
int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
u64 parent, u64 ref_root, u64 parent, u64 ref_root,
u64 owner, u64 offset, int action, u64 owner, u64 offset, int action,
struct btrfs_delayed_extent_op *extent_op) struct btrfs_delayed_extent_op *extent_op,
int for_cow)
{ {
struct btrfs_delayed_data_ref *ref; struct btrfs_delayed_data_ref *ref;
struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_head *head_ref;
...@@ -655,18 +665,20 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, ...@@ -655,18 +665,20 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
* insert both the head node and the new ref without dropping * insert both the head node and the new ref without dropping
* the spin lock * the spin lock
*/ */
ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, num_bytes, ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr,
action, 1); num_bytes, action, 1);
BUG_ON(ret); BUG_ON(ret);
ret = add_delayed_data_ref(trans, &ref->node, bytenr, num_bytes, ret = add_delayed_data_ref(fs_info, trans, &ref->node, bytenr,
parent, ref_root, owner, offset, action); num_bytes, parent, ref_root, owner, offset,
action, for_cow);
BUG_ON(ret); BUG_ON(ret);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
return 0; return 0;
} }
int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
struct btrfs_delayed_extent_op *extent_op) struct btrfs_delayed_extent_op *extent_op)
{ {
...@@ -683,7 +695,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, ...@@ -683,7 +695,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans,
delayed_refs = &trans->transaction->delayed_refs; delayed_refs = &trans->transaction->delayed_refs;
spin_lock(&delayed_refs->lock); spin_lock(&delayed_refs->lock);
ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr,
num_bytes, BTRFS_UPDATE_DELAYED_HEAD, num_bytes, BTRFS_UPDATE_DELAYED_HEAD,
extent_op->is_data); extent_op->is_data);
BUG_ON(ret); BUG_ON(ret);
......
...@@ -151,16 +151,21 @@ static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref) ...@@ -151,16 +151,21 @@ static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref)
} }
} }
int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 parent, u64 bytenr, u64 num_bytes, u64 parent,
u64 ref_root, int level, int action, u64 ref_root, int level, int action,
struct btrfs_delayed_extent_op *extent_op); struct btrfs_delayed_extent_op *extent_op,
int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, int for_cow);
int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
u64 parent, u64 ref_root, u64 parent, u64 ref_root,
u64 owner, u64 offset, int action, u64 owner, u64 offset, int action,
struct btrfs_delayed_extent_op *extent_op); struct btrfs_delayed_extent_op *extent_op,
int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, int for_cow);
int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes, u64 bytenr, u64 num_bytes,
struct btrfs_delayed_extent_op *extent_op); struct btrfs_delayed_extent_op *extent_op);
......
...@@ -1243,7 +1243,8 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, ...@@ -1243,7 +1243,8 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
root->ref_cows = 0; root->ref_cows = 0;
leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
BTRFS_TREE_LOG_OBJECTID, NULL, 0, 0, 0); BTRFS_TREE_LOG_OBJECTID, NULL,
0, 0, 0, 0);
if (IS_ERR(leaf)) { if (IS_ERR(leaf)) {
kfree(root); kfree(root);
return ERR_CAST(leaf); return ERR_CAST(leaf);
......
...@@ -1872,20 +1872,24 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, ...@@ -1872,20 +1872,24 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, int btrfs_inc_extent_ref(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,
u64 root_objectid, u64 owner, u64 offset) u64 root_objectid, u64 owner, u64 offset, int for_cow)
{ {
int ret; int ret;
struct btrfs_fs_info *fs_info = root->fs_info;
BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID && BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID &&
root_objectid == BTRFS_TREE_LOG_OBJECTID); root_objectid == BTRFS_TREE_LOG_OBJECTID);
if (owner < BTRFS_FIRST_FREE_OBJECTID) { if (owner < BTRFS_FIRST_FREE_OBJECTID) {
ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
num_bytes,
parent, root_objectid, (int)owner, parent, root_objectid, (int)owner,
BTRFS_ADD_DELAYED_REF, NULL); BTRFS_ADD_DELAYED_REF, NULL, for_cow);
} else { } else {
ret = btrfs_add_delayed_data_ref(trans, bytenr, num_bytes, ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
num_bytes,
parent, root_objectid, owner, offset, parent, root_objectid, owner, offset,
BTRFS_ADD_DELAYED_REF, NULL); BTRFS_ADD_DELAYED_REF, NULL, for_cow);
} }
return ret; return ret;
} }
...@@ -2405,7 +2409,8 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, ...@@ -2405,7 +2409,8 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
extent_op->update_key = 0; extent_op->update_key = 0;
extent_op->is_data = is_data ? 1 : 0; extent_op->is_data = is_data ? 1 : 0;
ret = btrfs_add_delayed_extent_op(trans, bytenr, num_bytes, extent_op); ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr,
num_bytes, extent_op);
if (ret) if (ret)
kfree(extent_op); kfree(extent_op);
return ret; return ret;
...@@ -2590,7 +2595,7 @@ int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, ...@@ -2590,7 +2595,7 @@ int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *buf, struct extent_buffer *buf,
int full_backref, int inc) int full_backref, int inc, int for_cow)
{ {
u64 bytenr; u64 bytenr;
u64 num_bytes; u64 num_bytes;
...@@ -2603,7 +2608,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, ...@@ -2603,7 +2608,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
int level; int level;
int ret = 0; int ret = 0;
int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
u64, u64, u64, u64, u64, u64); u64, u64, u64, u64, u64, u64, int);
ref_root = btrfs_header_owner(buf); ref_root = btrfs_header_owner(buf);
nritems = btrfs_header_nritems(buf); nritems = btrfs_header_nritems(buf);
...@@ -2640,14 +2645,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, ...@@ -2640,14 +2645,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
key.offset -= btrfs_file_extent_offset(buf, fi); key.offset -= btrfs_file_extent_offset(buf, fi);
ret = process_func(trans, root, bytenr, num_bytes, ret = process_func(trans, root, bytenr, num_bytes,
parent, ref_root, key.objectid, parent, ref_root, key.objectid,
key.offset); key.offset, for_cow);
if (ret) if (ret)
goto fail; goto fail;
} else { } else {
bytenr = btrfs_node_blockptr(buf, i); bytenr = btrfs_node_blockptr(buf, i);
num_bytes = btrfs_level_size(root, level - 1); num_bytes = btrfs_level_size(root, level - 1);
ret = process_func(trans, root, bytenr, num_bytes, ret = process_func(trans, root, bytenr, num_bytes,
parent, ref_root, level - 1, 0); parent, ref_root, level - 1, 0,
for_cow);
if (ret) if (ret)
goto fail; goto fail;
} }
...@@ -2659,15 +2665,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, ...@@ -2659,15 +2665,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
} }
int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct extent_buffer *buf, int full_backref) struct extent_buffer *buf, int full_backref, int for_cow)
{ {
return __btrfs_mod_ref(trans, root, buf, full_backref, 1); return __btrfs_mod_ref(trans, root, buf, full_backref, 1, for_cow);
} }
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 full_backref) struct extent_buffer *buf, int full_backref, int for_cow)
{ {
return __btrfs_mod_ref(trans, root, buf, full_backref, 0); return __btrfs_mod_ref(trans, root, buf, full_backref, 0, for_cow);
} }
static int write_one_cache_group(struct btrfs_trans_handle *trans, static int write_one_cache_group(struct btrfs_trans_handle *trans,
...@@ -4937,16 +4943,17 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, ...@@ -4937,16 +4943,17 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
void btrfs_free_tree_block(struct btrfs_trans_handle *trans, void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *buf, struct extent_buffer *buf,
u64 parent, int last_ref) u64 parent, int last_ref, int for_cow)
{ {
struct btrfs_block_group_cache *cache = NULL; struct btrfs_block_group_cache *cache = NULL;
int ret; int ret;
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
ret = btrfs_add_delayed_tree_ref(trans, buf->start, buf->len, ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
buf->start, buf->len,
parent, root->root_key.objectid, parent, root->root_key.objectid,
btrfs_header_level(buf), btrfs_header_level(buf),
BTRFS_DROP_DELAYED_REF, NULL); BTRFS_DROP_DELAYED_REF, NULL, for_cow);
BUG_ON(ret); BUG_ON(ret);
} }
...@@ -4981,12 +4988,12 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, ...@@ -4981,12 +4988,12 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
btrfs_put_block_group(cache); btrfs_put_block_group(cache);
} }
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 root_objectid,
u64 bytenr, u64 num_bytes, u64 parent, u64 owner, u64 offset, int for_cow)
u64 root_objectid, u64 owner, u64 offset)
{ {
int ret; int ret;
struct btrfs_fs_info *fs_info = root->fs_info;
/* /*
* tree log blocks never actually go into the extent allocation * tree log blocks never actually go into the extent allocation
...@@ -4998,14 +5005,17 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, ...@@ -4998,14 +5005,17 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
btrfs_pin_extent(root, bytenr, num_bytes, 1); btrfs_pin_extent(root, bytenr, num_bytes, 1);
ret = 0; ret = 0;
} else if (owner < BTRFS_FIRST_FREE_OBJECTID) { } else if (owner < BTRFS_FIRST_FREE_OBJECTID) {
ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
num_bytes,
parent, root_objectid, (int)owner, parent, root_objectid, (int)owner,
BTRFS_DROP_DELAYED_REF, NULL); BTRFS_DROP_DELAYED_REF, NULL, for_cow);
BUG_ON(ret); BUG_ON(ret);
} else { } else {
ret = btrfs_add_delayed_data_ref(trans, bytenr, num_bytes, ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
num_bytes,
parent, root_objectid, owner, parent, root_objectid, owner,
offset, BTRFS_DROP_DELAYED_REF, NULL); offset, BTRFS_DROP_DELAYED_REF,
NULL, for_cow);
BUG_ON(ret); BUG_ON(ret);
} }
return ret; return ret;
...@@ -5826,9 +5836,10 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, ...@@ -5826,9 +5836,10 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
ret = btrfs_add_delayed_data_ref(trans, ins->objectid, ins->offset, ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid,
0, root_objectid, owner, offset, ins->offset, 0,
BTRFS_ADD_DELAYED_EXTENT, NULL); root_objectid, owner, offset,
BTRFS_ADD_DELAYED_EXTENT, NULL, 0);
return ret; return ret;
} }
...@@ -5998,7 +6009,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, ...@@ -5998,7 +6009,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u32 blocksize, struct btrfs_root *root, u32 blocksize,
u64 parent, u64 root_objectid, u64 parent, u64 root_objectid,
struct btrfs_disk_key *key, int level, struct btrfs_disk_key *key, int level,
u64 hint, u64 empty_size) u64 hint, u64 empty_size, int for_cow)
{ {
struct btrfs_key ins; struct btrfs_key ins;
struct btrfs_block_rsv *block_rsv; struct btrfs_block_rsv *block_rsv;
...@@ -6042,10 +6053,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, ...@@ -6042,10 +6053,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
extent_op->update_flags = 1; extent_op->update_flags = 1;
extent_op->is_data = 0; extent_op->is_data = 0;
ret = btrfs_add_delayed_tree_ref(trans, ins.objectid, ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
ins.objectid,
ins.offset, parent, root_objectid, ins.offset, parent, root_objectid,
level, BTRFS_ADD_DELAYED_EXTENT, level, BTRFS_ADD_DELAYED_EXTENT,
extent_op); extent_op, for_cow);
BUG_ON(ret); BUG_ON(ret);
} }
return buf; return buf;
...@@ -6062,6 +6074,7 @@ struct walk_control { ...@@ -6062,6 +6074,7 @@ struct walk_control {
int keep_locks; int keep_locks;
int reada_slot; int reada_slot;
int reada_count; int reada_count;
int for_reloc;
}; };
#define DROP_REFERENCE 1 #define DROP_REFERENCE 1
...@@ -6200,9 +6213,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, ...@@ -6200,9 +6213,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
/* wc->stage == UPDATE_BACKREF */ /* wc->stage == UPDATE_BACKREF */
if (!(wc->flags[level] & flag)) { if (!(wc->flags[level] & flag)) {
BUG_ON(!path->locks[level]); BUG_ON(!path->locks[level]);
ret = btrfs_inc_ref(trans, root, eb, 1); ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_dec_ref(trans, root, eb, 0); ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_set_disk_extent_flags(trans, root, eb->start, ret = btrfs_set_disk_extent_flags(trans, root, eb->start,
eb->len, flag, 0); eb->len, flag, 0);
...@@ -6346,7 +6359,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, ...@@ -6346,7 +6359,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
} }
ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
root->root_key.objectid, level - 1, 0); root->root_key.objectid, level - 1, 0, 0);
BUG_ON(ret); BUG_ON(ret);
} }
btrfs_tree_unlock(next); btrfs_tree_unlock(next);
...@@ -6420,9 +6433,11 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, ...@@ -6420,9 +6433,11 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
if (wc->refs[level] == 1) { if (wc->refs[level] == 1) {
if (level == 0) { if (level == 0) {
if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF)
ret = btrfs_dec_ref(trans, root, eb, 1); ret = btrfs_dec_ref(trans, root, eb, 1,
wc->for_reloc);
else else
ret = btrfs_dec_ref(trans, root, eb, 0); ret = btrfs_dec_ref(trans, root, eb, 0,
wc->for_reloc);
BUG_ON(ret); BUG_ON(ret);
} }
/* make block locked assertion in clean_tree_block happy */ /* make block locked assertion in clean_tree_block happy */
...@@ -6449,7 +6464,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, ...@@ -6449,7 +6464,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
btrfs_header_owner(path->nodes[level + 1])); btrfs_header_owner(path->nodes[level + 1]));
} }
btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1); btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1, 0);
out: out:
wc->refs[level] = 0; wc->refs[level] = 0;
wc->flags[level] = 0; wc->flags[level] = 0;
...@@ -6533,7 +6548,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, ...@@ -6533,7 +6548,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
* blocks are properly updated. * blocks are properly updated.
*/ */
void btrfs_drop_snapshot(struct btrfs_root *root, void btrfs_drop_snapshot(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv, int update_ref) struct btrfs_block_rsv *block_rsv, int update_ref,
int for_reloc)
{ {
struct btrfs_path *path; struct btrfs_path *path;
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
...@@ -6621,6 +6637,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, ...@@ -6621,6 +6637,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root,
wc->stage = DROP_REFERENCE; wc->stage = DROP_REFERENCE;
wc->update_ref = update_ref; wc->update_ref = update_ref;
wc->keep_locks = 0; wc->keep_locks = 0;
wc->for_reloc = for_reloc;
wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root);
while (1) { while (1) {
...@@ -6705,6 +6722,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, ...@@ -6705,6 +6722,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root,
* drop subtree rooted at tree block 'node'. * drop subtree rooted at tree block 'node'.
* *
* NOTE: this function will unlock and release tree block 'node' * NOTE: this function will unlock and release tree block 'node'
* only used by relocation code
*/ */
int btrfs_drop_subtree(struct btrfs_trans_handle *trans, int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
...@@ -6749,6 +6767,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, ...@@ -6749,6 +6767,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
wc->stage = DROP_REFERENCE; wc->stage = DROP_REFERENCE;
wc->update_ref = 0; wc->update_ref = 0;
wc->keep_locks = 1; wc->keep_locks = 1;
wc->for_reloc = 1;
wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root);
while (1) { while (1) {
......
...@@ -678,7 +678,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, ...@@ -678,7 +678,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
disk_bytenr, num_bytes, 0, disk_bytenr, num_bytes, 0,
root->root_key.objectid, root->root_key.objectid,
new_key.objectid, new_key.objectid,
start - extent_offset); start - extent_offset, 0);
BUG_ON(ret); BUG_ON(ret);
*hint_byte = disk_bytenr; *hint_byte = disk_bytenr;
} }
...@@ -753,7 +753,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, ...@@ -753,7 +753,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
disk_bytenr, num_bytes, 0, disk_bytenr, num_bytes, 0,
root->root_key.objectid, root->root_key.objectid,
key.objectid, key.offset - key.objectid, key.offset -
extent_offset); extent_offset, 0);
BUG_ON(ret); BUG_ON(ret);
inode_sub_bytes(inode, inode_sub_bytes(inode,
extent_end - key.offset); extent_end - key.offset);
...@@ -962,7 +962,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ...@@ -962,7 +962,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0,
root->root_key.objectid, root->root_key.objectid,
ino, orig_offset); ino, orig_offset, 0);
BUG_ON(ret); BUG_ON(ret);
if (split == start) { if (split == start) {
...@@ -989,7 +989,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ...@@ -989,7 +989,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
del_nr++; del_nr++;
ret = btrfs_free_extent(trans, root, bytenr, num_bytes, ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
0, root->root_key.objectid, 0, root->root_key.objectid,
ino, orig_offset); ino, orig_offset, 0);
BUG_ON(ret); BUG_ON(ret);
} }
other_start = 0; other_start = 0;
...@@ -1006,7 +1006,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ...@@ -1006,7 +1006,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
del_nr++; del_nr++;
ret = btrfs_free_extent(trans, root, bytenr, num_bytes, ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
0, root->root_key.objectid, 0, root->root_key.objectid,
ino, orig_offset); ino, orig_offset, 0);
BUG_ON(ret); BUG_ON(ret);
} }
if (del_nr == 0) { if (del_nr == 0) {
......
...@@ -3139,7 +3139,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, ...@@ -3139,7 +3139,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
ret = btrfs_free_extent(trans, root, extent_start, ret = btrfs_free_extent(trans, root, extent_start,
extent_num_bytes, 0, extent_num_bytes, 0,
btrfs_header_owner(leaf), btrfs_header_owner(leaf),
ino, extent_offset); ino, extent_offset, 0);
BUG_ON(ret); BUG_ON(ret);
} }
......
...@@ -358,7 +358,7 @@ static noinline int create_subvol(struct btrfs_root *root, ...@@ -358,7 +358,7 @@ static noinline int create_subvol(struct btrfs_root *root,
return PTR_ERR(trans); return PTR_ERR(trans);
leaf = btrfs_alloc_free_block(trans, root, root->leafsize, leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
0, objectid, NULL, 0, 0, 0); 0, objectid, NULL, 0, 0, 0, 0);
if (IS_ERR(leaf)) { if (IS_ERR(leaf)) {
ret = PTR_ERR(leaf); ret = PTR_ERR(leaf);
goto fail; goto fail;
...@@ -2425,7 +2425,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ...@@ -2425,7 +2425,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
disko, diskl, 0, disko, diskl, 0,
root->root_key.objectid, root->root_key.objectid,
btrfs_ino(inode), btrfs_ino(inode),
new_key.offset - datao); new_key.offset - datao,
0);
BUG_ON(ret); BUG_ON(ret);
} }
} else if (type == BTRFS_FILE_EXTENT_INLINE) { } else if (type == BTRFS_FILE_EXTENT_INLINE) {
......
...@@ -1604,12 +1604,12 @@ int replace_file_extents(struct btrfs_trans_handle *trans, ...@@ -1604,12 +1604,12 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
ret = btrfs_inc_extent_ref(trans, root, new_bytenr, ret = btrfs_inc_extent_ref(trans, root, new_bytenr,
num_bytes, parent, num_bytes, parent,
btrfs_header_owner(leaf), btrfs_header_owner(leaf),
key.objectid, key.offset); key.objectid, key.offset, 1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_free_extent(trans, root, bytenr, num_bytes, ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
parent, btrfs_header_owner(leaf), parent, btrfs_header_owner(leaf),
key.objectid, key.offset); key.objectid, key.offset, 1);
BUG_ON(ret); BUG_ON(ret);
} }
if (dirty) if (dirty)
...@@ -1778,21 +1778,23 @@ int replace_path(struct btrfs_trans_handle *trans, ...@@ -1778,21 +1778,23 @@ int replace_path(struct btrfs_trans_handle *trans,
ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize, ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize,
path->nodes[level]->start, path->nodes[level]->start,
src->root_key.objectid, level - 1, 0); src->root_key.objectid, level - 1, 0,
1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize, ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize,
0, dest->root_key.objectid, level - 1, 0, dest->root_key.objectid, level - 1,
0); 0, 1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_free_extent(trans, src, new_bytenr, blocksize, ret = btrfs_free_extent(trans, src, new_bytenr, blocksize,
path->nodes[level]->start, path->nodes[level]->start,
src->root_key.objectid, level - 1, 0); src->root_key.objectid, level - 1, 0,
1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize, ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize,
0, dest->root_key.objectid, level - 1, 0, dest->root_key.objectid, level - 1,
0); 0, 1);
BUG_ON(ret); BUG_ON(ret);
btrfs_unlock_up_safe(path, 0); btrfs_unlock_up_safe(path, 0);
...@@ -2244,7 +2246,7 @@ int merge_reloc_roots(struct reloc_control *rc) ...@@ -2244,7 +2246,7 @@ int merge_reloc_roots(struct reloc_control *rc)
} else { } else {
list_del_init(&reloc_root->root_list); list_del_init(&reloc_root->root_list);
} }
btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0); btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1);
} }
if (found) { if (found) {
...@@ -2558,7 +2560,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, ...@@ -2558,7 +2560,7 @@ static int do_relocation(struct btrfs_trans_handle *trans,
node->eb->start, blocksize, node->eb->start, blocksize,
upper->eb->start, upper->eb->start,
btrfs_header_owner(upper->eb), btrfs_header_owner(upper->eb),
node->level, 0); node->level, 0, 1);
BUG_ON(ret); BUG_ON(ret);
ret = btrfs_drop_subtree(trans, root, eb, upper->eb); ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
......
...@@ -1393,9 +1393,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) ...@@ -1393,9 +1393,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root)
if (btrfs_header_backref_rev(root->node) < if (btrfs_header_backref_rev(root->node) <
BTRFS_MIXED_BACKREF_REV) BTRFS_MIXED_BACKREF_REV)
btrfs_drop_snapshot(root, NULL, 0); btrfs_drop_snapshot(root, NULL, 0, 0);
else else
btrfs_drop_snapshot(root, NULL, 1); btrfs_drop_snapshot(root, NULL, 1, 0);
} }
return 0; return 0;
} }
...@@ -589,7 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, ...@@ -589,7 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
ret = btrfs_inc_extent_ref(trans, root, ret = btrfs_inc_extent_ref(trans, root,
ins.objectid, ins.offset, ins.objectid, ins.offset,
0, root->root_key.objectid, 0, root->root_key.objectid,
key->objectid, offset); key->objectid, offset, 0);
BUG_ON(ret); BUG_ON(ret);
} else { } else {
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment