Skip to content

Commit

Permalink
btrfs: move transaction aborts to the point of failure
Browse files Browse the repository at this point in the history
Call btrfs_abort_transaction as early as possible when an error
condition is detected, that way the line number reported is useful
and we're not clueless anymore which error path led to the abort.

Signed-off-by: David Sterba <dsterba@suse.cz>
  • Loading branch information
David Sterba authored and Chris Mason committed Oct 9, 2012
1 parent 8732d44 commit 005d642
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 47 deletions.
5 changes: 5 additions & 0 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3400,6 +3400,11 @@ static inline void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info,
}
}

/*
* Call btrfs_abort_transaction as early as possible when an error condition is
* detected, that way the exact line number is reported.
*/

#define btrfs_abort_transaction(trans, root, errno) \
do { \
__btrfs_abort_transaction(trans, root, __func__, \
Expand Down
56 changes: 35 additions & 21 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -5123,8 +5123,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
ret = remove_extent_backref(trans, extent_root, path,
NULL, refs_to_drop,
is_data);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}
btrfs_release_path(path);
path->leave_spinning = 1;

Expand All @@ -5142,8 +5144,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
btrfs_print_leaf(extent_root,
path->nodes[0]);
}
if (ret < 0)
goto abort;
if (ret < 0) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}
extent_slot = path->slots[0];
}
} else if (ret == -ENOENT) {
Expand All @@ -5157,7 +5161,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
(unsigned long long)owner_objectid,
(unsigned long long)owner_offset);
} else {
goto abort;
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}

leaf = path->nodes[0];
Expand All @@ -5167,8 +5172,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
BUG_ON(found_extent || extent_slot != path->slots[0]);
ret = convert_extent_item_v0(trans, extent_root, path,
owner_objectid, 0);
if (ret < 0)
goto abort;
if (ret < 0) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}

btrfs_release_path(path);
path->leave_spinning = 1;
Expand All @@ -5185,8 +5192,11 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
(unsigned long long)bytenr);
btrfs_print_leaf(extent_root, path->nodes[0]);
}
if (ret < 0)
goto abort;
if (ret < 0) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}

extent_slot = path->slots[0];
leaf = path->nodes[0];
item_size = btrfs_item_size_nr(leaf, extent_slot);
Expand Down Expand Up @@ -5223,8 +5233,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
ret = remove_extent_backref(trans, extent_root, path,
iref, refs_to_drop,
is_data);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}
}
} else {
if (found_extent) {
Expand All @@ -5241,27 +5253,29 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,

ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
num_to_del);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}
btrfs_release_path(path);

if (is_data) {
ret = btrfs_del_csums(trans, root, bytenr, num_bytes);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}
}

ret = update_block_group(trans, root, bytenr, num_bytes, 0);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}
}
out:
btrfs_free_path(path);
return ret;

abort:
btrfs_abort_transaction(trans, extent_root, ret);
goto out;
}

/*
Expand Down
29 changes: 17 additions & 12 deletions fs/btrfs/root-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
return -ENOMEM;

ret = btrfs_search_slot(trans, root, key, path, 0, 1);
if (ret < 0)
goto out_abort;
if (ret < 0) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}

if (ret != 0) {
btrfs_print_leaf(root, path->nodes[0]);
Expand All @@ -166,16 +168,23 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_release_path(path);
ret = btrfs_search_slot(trans, root, key, path,
-1, 1);
if (ret < 0)
goto out_abort;
if (ret < 0) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}

ret = btrfs_del_item(trans, root, path);
if (ret < 0)
goto out_abort;
if (ret < 0) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}
btrfs_release_path(path);
ret = btrfs_insert_empty_item(trans, root, path,
key, sizeof(*item));
if (ret < 0)
goto out_abort;
if (ret < 0) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}
l = path->nodes[0];
slot = path->slots[0];
ptr = btrfs_item_ptr_offset(l, slot);
Expand All @@ -192,10 +201,6 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
out:
btrfs_free_path(path);
return ret;

out_abort:
btrfs_abort_transaction(trans, root, ret);
goto out;
}

int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
Expand Down
37 changes: 23 additions & 14 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1775,15 +1775,21 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)

if (seeding_dev) {
ret = init_first_rw_device(trans, root, device);
if (ret)
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto error_trans;
}
ret = btrfs_finish_sprout(trans, root);
if (ret)
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto error_trans;
}
} else {
ret = btrfs_add_device(trans, root, device);
if (ret)
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto error_trans;
}
}

/*
Expand Down Expand Up @@ -1814,7 +1820,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)

error_trans:
unlock_chunks(root);
btrfs_abort_transaction(trans, root, ret);
btrfs_end_transaction(trans, root);
rcu_string_free(device->name);
kfree(device);
Expand Down Expand Up @@ -3608,12 +3613,16 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
ret = __btrfs_alloc_chunk(trans, extent_root, &sys_map,
&sys_chunk_size, &sys_stripe_size,
sys_chunk_offset, alloc_profile);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}

ret = btrfs_add_device(trans, fs_info->chunk_root, device);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}

/*
* Modifying chunk tree needs allocating new blocks from both
Expand All @@ -3623,19 +3632,19 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
*/
ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset,
chunk_size, stripe_size);
if (ret)
goto abort;
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto out;
}

ret = __finish_chunk_alloc(trans, extent_root, sys_map,
sys_chunk_offset, sys_chunk_size,
sys_stripe_size);
if (ret)
goto abort;
btrfs_abort_transaction(trans, root, ret);

return 0;
out:

abort:
btrfs_abort_transaction(trans, root, ret);
return ret;
}

Expand Down

0 comments on commit 005d642

Please sign in to comment.