Commit 9631e4cc authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: introduce BTRFS_NESTING_COW for cow'ing blocks

When we COW a block we are holding a lock on the original block, and
then we lock the new COW block.  Because our lockdep maps are based on
root + level, this will make lockdep complain.  We need a way to
indicate a subclass for locking the COW'ed block, so plumb through our
btrfs_lock_nesting from btrfs_cow_block down to the btrfs_init_buffer,
and then introduce BTRFS_NESTING_COW to be used for cow'ing blocks.

The reason I've added all this extra infrastructure is because there
will be need of different nesting classes in follow up patches.
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent fd7ba1c1
...@@ -198,7 +198,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, ...@@ -198,7 +198,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
btrfs_node_key(buf, &disk_key, 0); btrfs_node_key(buf, &disk_key, 0);
cow = btrfs_alloc_tree_block(trans, root, 0, new_root_objectid, cow = btrfs_alloc_tree_block(trans, root, 0, new_root_objectid,
&disk_key, level, buf->start, 0); &disk_key, level, buf->start, 0, BTRFS_NESTING_NORMAL);
if (IS_ERR(cow)) if (IS_ERR(cow))
return PTR_ERR(cow); return PTR_ERR(cow);
...@@ -957,7 +957,8 @@ static struct extent_buffer *alloc_tree_block_no_bg_flush( ...@@ -957,7 +957,8 @@ static struct extent_buffer *alloc_tree_block_no_bg_flush(
const struct btrfs_disk_key *disk_key, const struct btrfs_disk_key *disk_key,
int level, int level,
u64 hint, u64 hint,
u64 empty_size) u64 empty_size,
enum btrfs_lock_nesting nest)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *ret; struct extent_buffer *ret;
...@@ -986,7 +987,7 @@ static struct extent_buffer *alloc_tree_block_no_bg_flush( ...@@ -986,7 +987,7 @@ static struct extent_buffer *alloc_tree_block_no_bg_flush(
ret = btrfs_alloc_tree_block(trans, root, parent_start, ret = btrfs_alloc_tree_block(trans, root, parent_start,
root->root_key.objectid, disk_key, level, root->root_key.objectid, disk_key, level,
hint, empty_size); hint, empty_size, nest);
trans->can_flush_pending_bgs = true; trans->can_flush_pending_bgs = true;
return ret; return ret;
...@@ -1009,7 +1010,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -1009,7 +1010,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
struct extent_buffer *buf, struct extent_buffer *buf,
struct extent_buffer *parent, int parent_slot, struct extent_buffer *parent, int parent_slot,
struct extent_buffer **cow_ret, struct extent_buffer **cow_ret,
u64 search_start, u64 empty_size) u64 search_start, u64 empty_size,
enum btrfs_lock_nesting nest)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_disk_key disk_key; struct btrfs_disk_key disk_key;
...@@ -1040,7 +1042,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -1040,7 +1042,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
parent_start = parent->start; parent_start = parent->start;
cow = alloc_tree_block_no_bg_flush(trans, root, parent_start, &disk_key, cow = alloc_tree_block_no_bg_flush(trans, root, parent_start, &disk_key,
level, search_start, empty_size); level, search_start, empty_size, nest);
if (IS_ERR(cow)) if (IS_ERR(cow))
return PTR_ERR(cow); return PTR_ERR(cow);
...@@ -1446,7 +1448,8 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, ...@@ -1446,7 +1448,8 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf, struct btrfs_root *root, struct extent_buffer *buf,
struct extent_buffer *parent, int parent_slot, struct extent_buffer *parent, int parent_slot,
struct extent_buffer **cow_ret) struct extent_buffer **cow_ret,
enum btrfs_lock_nesting nest)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
u64 search_start; u64 search_start;
...@@ -1485,7 +1488,7 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -1485,7 +1488,7 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
*/ */
btrfs_qgroup_trace_subtree_after_cow(trans, root, buf); btrfs_qgroup_trace_subtree_after_cow(trans, root, buf);
ret = __btrfs_cow_block(trans, root, buf, parent, ret = __btrfs_cow_block(trans, root, buf, parent,
parent_slot, cow_ret, search_start, 0); parent_slot, cow_ret, search_start, 0, nest);
trace_btrfs_cow_block(root, buf, *cow_ret); trace_btrfs_cow_block(root, buf, *cow_ret);
...@@ -1657,7 +1660,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, ...@@ -1657,7 +1660,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
err = __btrfs_cow_block(trans, root, cur, parent, i, err = __btrfs_cow_block(trans, root, cur, parent, i,
&cur, search_start, &cur, search_start,
min(16 * blocksize, min(16 * blocksize,
(end_slot - i) * blocksize)); (end_slot - i) * blocksize),
BTRFS_NESTING_COW);
if (err) { if (err) {
btrfs_tree_unlock(cur); btrfs_tree_unlock(cur);
free_extent_buffer(cur); free_extent_buffer(cur);
...@@ -1855,7 +1859,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1855,7 +1859,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_tree_lock(child); btrfs_tree_lock(child);
btrfs_set_lock_blocking_write(child); btrfs_set_lock_blocking_write(child);
ret = btrfs_cow_block(trans, root, child, mid, 0, &child); ret = btrfs_cow_block(trans, root, child, mid, 0, &child,
BTRFS_NESTING_COW);
if (ret) { if (ret) {
btrfs_tree_unlock(child); btrfs_tree_unlock(child);
free_extent_buffer(child); free_extent_buffer(child);
...@@ -1894,7 +1899,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1894,7 +1899,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_tree_lock(left); btrfs_tree_lock(left);
btrfs_set_lock_blocking_write(left); btrfs_set_lock_blocking_write(left);
wret = btrfs_cow_block(trans, root, left, wret = btrfs_cow_block(trans, root, left,
parent, pslot - 1, &left); parent, pslot - 1, &left,
BTRFS_NESTING_COW);
if (wret) { if (wret) {
ret = wret; ret = wret;
goto enospc; goto enospc;
...@@ -1909,7 +1915,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1909,7 +1915,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_tree_lock(right); btrfs_tree_lock(right);
btrfs_set_lock_blocking_write(right); btrfs_set_lock_blocking_write(right);
wret = btrfs_cow_block(trans, root, right, wret = btrfs_cow_block(trans, root, right,
parent, pslot + 1, &right); parent, pslot + 1, &right,
BTRFS_NESTING_COW);
if (wret) { if (wret) {
ret = wret; ret = wret;
goto enospc; goto enospc;
...@@ -2077,7 +2084,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, ...@@ -2077,7 +2084,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
wret = 1; wret = 1;
} else { } else {
ret = btrfs_cow_block(trans, root, left, parent, ret = btrfs_cow_block(trans, root, left, parent,
pslot - 1, &left); pslot - 1, &left,
BTRFS_NESTING_COW);
if (ret) if (ret)
wret = 1; wret = 1;
else { else {
...@@ -2132,7 +2140,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, ...@@ -2132,7 +2140,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
} else { } else {
ret = btrfs_cow_block(trans, root, right, ret = btrfs_cow_block(trans, root, right,
parent, pslot + 1, parent, pslot + 1,
&right); &right, BTRFS_NESTING_COW);
if (ret) if (ret)
wret = 1; wret = 1;
else { else {
...@@ -2740,11 +2748,13 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, ...@@ -2740,11 +2748,13 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
btrfs_set_path_blocking(p); btrfs_set_path_blocking(p);
if (last_level) if (last_level)
err = btrfs_cow_block(trans, root, b, NULL, 0, err = btrfs_cow_block(trans, root, b, NULL, 0,
&b); &b,
BTRFS_NESTING_COW);
else else
err = btrfs_cow_block(trans, root, b, err = btrfs_cow_block(trans, root, b,
p->nodes[level + 1], p->nodes[level + 1],
p->slots[level + 1], &b); p->slots[level + 1], &b,
BTRFS_NESTING_COW);
if (err) { if (err) {
ret = err; ret = err;
goto done; goto done;
...@@ -3396,7 +3406,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, ...@@ -3396,7 +3406,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
btrfs_node_key(lower, &lower_key, 0); btrfs_node_key(lower, &lower_key, 0);
c = alloc_tree_block_no_bg_flush(trans, root, 0, &lower_key, level, c = alloc_tree_block_no_bg_flush(trans, root, 0, &lower_key, level,
root->node->start, 0); root->node->start, 0,
BTRFS_NESTING_NORMAL);
if (IS_ERR(c)) if (IS_ERR(c))
return PTR_ERR(c); return PTR_ERR(c);
...@@ -3526,7 +3537,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, ...@@ -3526,7 +3537,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
btrfs_node_key(c, &disk_key, mid); btrfs_node_key(c, &disk_key, mid);
split = alloc_tree_block_no_bg_flush(trans, root, 0, &disk_key, level, split = alloc_tree_block_no_bg_flush(trans, root, 0, &disk_key, level,
c->start, 0); c->start, 0, BTRFS_NESTING_NORMAL);
if (IS_ERR(split)) if (IS_ERR(split))
return PTR_ERR(split); return PTR_ERR(split);
...@@ -3804,7 +3815,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -3804,7 +3815,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
/* cow and double check */ /* cow and double check */
ret = btrfs_cow_block(trans, root, right, upper, ret = btrfs_cow_block(trans, root, right, upper,
slot + 1, &right); slot + 1, &right, BTRFS_NESTING_COW);
if (ret) if (ret)
goto out_unlock; goto out_unlock;
...@@ -4045,7 +4056,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -4045,7 +4056,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
/* cow and double check */ /* cow and double check */
ret = btrfs_cow_block(trans, root, left, ret = btrfs_cow_block(trans, root, left,
path->nodes[1], slot - 1, &left); path->nodes[1], slot - 1, &left,
BTRFS_NESTING_COW);
if (ret) { if (ret) {
/* we hit -ENOSPC, but it isn't fatal here */ /* we hit -ENOSPC, but it isn't fatal here */
if (ret == -ENOSPC) if (ret == -ENOSPC)
...@@ -4312,7 +4324,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, ...@@ -4312,7 +4324,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
btrfs_item_key(l, &disk_key, mid); btrfs_item_key(l, &disk_key, mid);
right = alloc_tree_block_no_bg_flush(trans, root, 0, &disk_key, 0, right = alloc_tree_block_no_bg_flush(trans, root, 0, &disk_key, 0,
l->start, 0); l->start, 0, BTRFS_NESTING_NORMAL);
if (IS_ERR(right)) if (IS_ERR(right))
return PTR_ERR(right); return PTR_ERR(right);
......
...@@ -2526,7 +2526,8 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, ...@@ -2526,7 +2526,8 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
u64 parent, u64 root_objectid, u64 parent, u64 root_objectid,
const struct btrfs_disk_key *key, const struct btrfs_disk_key *key,
int level, u64 hint, int level, u64 hint,
u64 empty_size); u64 empty_size,
enum btrfs_lock_nesting nest);
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,
...@@ -2667,7 +2668,8 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, ...@@ -2667,7 +2668,8 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent,
int btrfs_cow_block(struct btrfs_trans_handle *trans, int btrfs_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf, struct btrfs_root *root, struct extent_buffer *buf,
struct extent_buffer *parent, int parent_slot, struct extent_buffer *parent, int parent_slot,
struct extent_buffer **cow_ret); struct extent_buffer **cow_ret,
enum btrfs_lock_nesting nest);
int btrfs_copy_root(struct btrfs_trans_handle *trans, int btrfs_copy_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *buf, struct extent_buffer *buf,
......
...@@ -1205,7 +1205,8 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, ...@@ -1205,7 +1205,8 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
root->root_key.type = BTRFS_ROOT_ITEM_KEY; root->root_key.type = BTRFS_ROOT_ITEM_KEY;
root->root_key.offset = 0; root->root_key.offset = 0;
leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0); leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0,
BTRFS_NESTING_NORMAL);
if (IS_ERR(leaf)) { if (IS_ERR(leaf)) {
ret = PTR_ERR(leaf); ret = PTR_ERR(leaf);
leaf = NULL; leaf = NULL;
...@@ -1277,7 +1278,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, ...@@ -1277,7 +1278,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
*/ */
leaf = btrfs_alloc_tree_block(trans, root, 0, BTRFS_TREE_LOG_OBJECTID, leaf = btrfs_alloc_tree_block(trans, root, 0, BTRFS_TREE_LOG_OBJECTID,
NULL, 0, 0, 0); NULL, 0, 0, 0, BTRFS_NESTING_NORMAL);
if (IS_ERR(leaf)) { if (IS_ERR(leaf)) {
btrfs_put_root(root); btrfs_put_root(root);
return ERR_CAST(leaf); return ERR_CAST(leaf);
......
...@@ -4656,7 +4656,8 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, ...@@ -4656,7 +4656,8 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
static struct extent_buffer * static struct extent_buffer *
btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
u64 bytenr, int level, u64 owner) u64 bytenr, int level, u64 owner,
enum btrfs_lock_nesting nest)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *buf; struct extent_buffer *buf;
...@@ -4679,7 +4680,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, ...@@ -4679,7 +4680,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
} }
btrfs_set_buffer_lockdep_class(owner, buf, level); btrfs_set_buffer_lockdep_class(owner, buf, level);
btrfs_tree_lock(buf); __btrfs_tree_lock(buf, nest);
btrfs_clean_tree_block(buf); btrfs_clean_tree_block(buf);
clear_bit(EXTENT_BUFFER_STALE, &buf->bflags); clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);
...@@ -4725,7 +4726,8 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, ...@@ -4725,7 +4726,8 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
u64 parent, u64 root_objectid, u64 parent, u64 root_objectid,
const struct btrfs_disk_key *key, const struct btrfs_disk_key *key,
int level, u64 hint, int level, u64 hint,
u64 empty_size) u64 empty_size,
enum btrfs_lock_nesting nest)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_key ins; struct btrfs_key ins;
...@@ -4741,7 +4743,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, ...@@ -4741,7 +4743,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
if (btrfs_is_testing(fs_info)) { if (btrfs_is_testing(fs_info)) {
buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr, buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr,
level, root_objectid); level, root_objectid, nest);
if (!IS_ERR(buf)) if (!IS_ERR(buf))
root->alloc_bytenr += blocksize; root->alloc_bytenr += blocksize;
return buf; return buf;
...@@ -4758,7 +4760,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, ...@@ -4758,7 +4760,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
goto out_unuse; goto out_unuse;
buf = btrfs_init_new_buffer(trans, root, ins.objectid, level, buf = btrfs_init_new_buffer(trans, root, ins.objectid, level,
root_objectid); root_objectid, nest);
if (IS_ERR(buf)) { if (IS_ERR(buf)) {
ret = PTR_ERR(buf); ret = PTR_ERR(buf);
goto out_free_reserved; goto out_free_reserved;
......
...@@ -628,7 +628,8 @@ static noinline int create_subvol(struct inode *dir, ...@@ -628,7 +628,8 @@ static noinline int create_subvol(struct inode *dir,
if (ret) if (ret)
goto fail; goto fail;
leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0); leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0,
BTRFS_NESTING_NORMAL);
if (IS_ERR(leaf)) { if (IS_ERR(leaf)) {
ret = PTR_ERR(leaf); ret = PTR_ERR(leaf);
goto fail; goto fail;
......
...@@ -24,6 +24,14 @@ ...@@ -24,6 +24,14 @@
enum btrfs_lock_nesting { enum btrfs_lock_nesting {
BTRFS_NESTING_NORMAL, BTRFS_NESTING_NORMAL,
/*
* When we COW a block we are holding the lock on the original block,
* and since our lockdep maps are rootid+level, this confuses lockdep
* when we lock the newly allocated COW'd block. Handle this by having
* a subclass for COW'ed blocks so that lockdep doesn't complain.
*/
BTRFS_NESTING_COW,
/* /*
* We are limited to MAX_LOCKDEP_SUBLCLASSES number of subclasses, so * We are limited to MAX_LOCKDEP_SUBLCLASSES number of subclasses, so
* add this in here and add a static_assert to keep us from going over * add this in here and add a static_assert to keep us from going over
......
...@@ -1206,7 +1206,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, ...@@ -1206,7 +1206,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
} }
if (cow) { if (cow) {
ret = btrfs_cow_block(trans, dest, eb, NULL, 0, &eb); ret = btrfs_cow_block(trans, dest, eb, NULL, 0, &eb,
BTRFS_NESTING_COW);
BUG_ON(ret); BUG_ON(ret);
} }
btrfs_set_lock_blocking_write(eb); btrfs_set_lock_blocking_write(eb);
...@@ -1274,7 +1275,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, ...@@ -1274,7 +1275,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
btrfs_tree_lock(eb); btrfs_tree_lock(eb);
if (cow) { if (cow) {
ret = btrfs_cow_block(trans, dest, eb, parent, ret = btrfs_cow_block(trans, dest, eb, parent,
slot, &eb); slot, &eb,
BTRFS_NESTING_COW);
BUG_ON(ret); BUG_ON(ret);
} }
btrfs_set_lock_blocking_write(eb); btrfs_set_lock_blocking_write(eb);
...@@ -1781,7 +1783,8 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, ...@@ -1781,7 +1783,8 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
* relocated and the block is tree root. * relocated and the block is tree root.
*/ */
leaf = btrfs_lock_root_node(root); leaf = btrfs_lock_root_node(root);
ret = btrfs_cow_block(trans, root, leaf, NULL, 0, &leaf); ret = btrfs_cow_block(trans, root, leaf, NULL, 0, &leaf,
BTRFS_NESTING_COW);
btrfs_tree_unlock(leaf); btrfs_tree_unlock(leaf);
free_extent_buffer(leaf); free_extent_buffer(leaf);
if (ret < 0) if (ret < 0)
...@@ -2308,7 +2311,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, ...@@ -2308,7 +2311,7 @@ static int do_relocation(struct btrfs_trans_handle *trans,
if (!node->eb) { if (!node->eb) {
ret = btrfs_cow_block(trans, root, eb, upper->eb, ret = btrfs_cow_block(trans, root, eb, upper->eb,
slot, &eb); slot, &eb, BTRFS_NESTING_COW);
btrfs_tree_unlock(eb); btrfs_tree_unlock(eb);
free_extent_buffer(eb); free_extent_buffer(eb);
if (ret < 0) { if (ret < 0) {
......
...@@ -1184,7 +1184,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans) ...@@ -1184,7 +1184,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans)
eb = btrfs_lock_root_node(fs_info->tree_root); eb = btrfs_lock_root_node(fs_info->tree_root);
ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL,
0, &eb); 0, &eb, BTRFS_NESTING_COW);
btrfs_tree_unlock(eb); btrfs_tree_unlock(eb);
free_extent_buffer(eb); free_extent_buffer(eb);
...@@ -1589,7 +1589,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, ...@@ -1589,7 +1589,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
btrfs_set_root_otransid(new_root_item, trans->transid); btrfs_set_root_otransid(new_root_item, trans->transid);
old = btrfs_lock_root_node(root); old = btrfs_lock_root_node(root);
ret = btrfs_cow_block(trans, root, old, NULL, 0, &old); ret = btrfs_cow_block(trans, root, old, NULL, 0, &old,
BTRFS_NESTING_COW);
if (ret) { if (ret) {
btrfs_tree_unlock(old); btrfs_tree_unlock(old);
free_extent_buffer(old); free_extent_buffer(old);
......
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