diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 1372057e1ec1..399521ab61da 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -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__, \ diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a3a902fdeb49..395e222e39ab 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -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; @@ -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) { @@ -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]; @@ -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; @@ -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); @@ -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) { @@ -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; } /* diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 10d8e4d88071..eb923d087da7 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -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]); @@ -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); @@ -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, diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 88b969aeeb71..4f4de51b5bdd 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -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; + } } /* @@ -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); @@ -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 @@ -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; }