aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2012-09-18 09:52:32 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-08 20:09:02 -0400
commit005d6427ac4f276d937a36ca6a1d62b181ed70bf (patch)
treea17de085350c5137e669774f0a810010997b95de /fs/btrfs
parent8732d44f806a9da9a7ca4d1704b8a1ed81639bc4 (diff)
btrfs: move transaction aborts to the point of failure
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>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/extent-tree.c56
-rw-r--r--fs/btrfs/root-tree.c29
-rw-r--r--fs/btrfs/volumes.c37
4 files changed, 80 insertions, 47 deletions
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,
3400 } 3400 }
3401} 3401}
3402 3402
3403/*
3404 * Call btrfs_abort_transaction as early as possible when an error condition is
3405 * detected, that way the exact line number is reported.
3406 */
3407
3403#define btrfs_abort_transaction(trans, root, errno) \ 3408#define btrfs_abort_transaction(trans, root, errno) \
3404do { \ 3409do { \
3405 __btrfs_abort_transaction(trans, root, __func__, \ 3410 __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,
5123 ret = remove_extent_backref(trans, extent_root, path, 5123 ret = remove_extent_backref(trans, extent_root, path,
5124 NULL, refs_to_drop, 5124 NULL, refs_to_drop,
5125 is_data); 5125 is_data);
5126 if (ret) 5126 if (ret) {
5127 goto abort; 5127 btrfs_abort_transaction(trans, extent_root, ret);
5128 goto out;
5129 }
5128 btrfs_release_path(path); 5130 btrfs_release_path(path);
5129 path->leave_spinning = 1; 5131 path->leave_spinning = 1;
5130 5132
@@ -5142,8 +5144,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5142 btrfs_print_leaf(extent_root, 5144 btrfs_print_leaf(extent_root,
5143 path->nodes[0]); 5145 path->nodes[0]);
5144 } 5146 }
5145 if (ret < 0) 5147 if (ret < 0) {
5146 goto abort; 5148 btrfs_abort_transaction(trans, extent_root, ret);
5149 goto out;
5150 }
5147 extent_slot = path->slots[0]; 5151 extent_slot = path->slots[0];
5148 } 5152 }
5149 } else if (ret == -ENOENT) { 5153 } else if (ret == -ENOENT) {
@@ -5157,7 +5161,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5157 (unsigned long long)owner_objectid, 5161 (unsigned long long)owner_objectid,
5158 (unsigned long long)owner_offset); 5162 (unsigned long long)owner_offset);
5159 } else { 5163 } else {
5160 goto abort; 5164 btrfs_abort_transaction(trans, extent_root, ret);
5165 goto out;
5161 } 5166 }
5162 5167
5163 leaf = path->nodes[0]; 5168 leaf = path->nodes[0];
@@ -5167,8 +5172,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5167 BUG_ON(found_extent || extent_slot != path->slots[0]); 5172 BUG_ON(found_extent || extent_slot != path->slots[0]);
5168 ret = convert_extent_item_v0(trans, extent_root, path, 5173 ret = convert_extent_item_v0(trans, extent_root, path,
5169 owner_objectid, 0); 5174 owner_objectid, 0);
5170 if (ret < 0) 5175 if (ret < 0) {
5171 goto abort; 5176 btrfs_abort_transaction(trans, extent_root, ret);
5177 goto out;
5178 }
5172 5179
5173 btrfs_release_path(path); 5180 btrfs_release_path(path);
5174 path->leave_spinning = 1; 5181 path->leave_spinning = 1;
@@ -5185,8 +5192,11 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5185 (unsigned long long)bytenr); 5192 (unsigned long long)bytenr);
5186 btrfs_print_leaf(extent_root, path->nodes[0]); 5193 btrfs_print_leaf(extent_root, path->nodes[0]);
5187 } 5194 }
5188 if (ret < 0) 5195 if (ret < 0) {
5189 goto abort; 5196 btrfs_abort_transaction(trans, extent_root, ret);
5197 goto out;
5198 }
5199
5190 extent_slot = path->slots[0]; 5200 extent_slot = path->slots[0];
5191 leaf = path->nodes[0]; 5201 leaf = path->nodes[0];
5192 item_size = btrfs_item_size_nr(leaf, extent_slot); 5202 item_size = btrfs_item_size_nr(leaf, extent_slot);
@@ -5223,8 +5233,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5223 ret = remove_extent_backref(trans, extent_root, path, 5233 ret = remove_extent_backref(trans, extent_root, path,
5224 iref, refs_to_drop, 5234 iref, refs_to_drop,
5225 is_data); 5235 is_data);
5226 if (ret) 5236 if (ret) {
5227 goto abort; 5237 btrfs_abort_transaction(trans, extent_root, ret);
5238 goto out;
5239 }
5228 } 5240 }
5229 } else { 5241 } else {
5230 if (found_extent) { 5242 if (found_extent) {
@@ -5241,27 +5253,29 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5241 5253
5242 ret = btrfs_del_items(trans, extent_root, path, path->slots[0], 5254 ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
5243 num_to_del); 5255 num_to_del);
5244 if (ret) 5256 if (ret) {
5245 goto abort; 5257 btrfs_abort_transaction(trans, extent_root, ret);
5258 goto out;
5259 }
5246 btrfs_release_path(path); 5260 btrfs_release_path(path);
5247 5261
5248 if (is_data) { 5262 if (is_data) {
5249 ret = btrfs_del_csums(trans, root, bytenr, num_bytes); 5263 ret = btrfs_del_csums(trans, root, bytenr, num_bytes);
5250 if (ret) 5264 if (ret) {
5251 goto abort; 5265 btrfs_abort_transaction(trans, extent_root, ret);
5266 goto out;
5267 }
5252 } 5268 }
5253 5269
5254 ret = update_block_group(trans, root, bytenr, num_bytes, 0); 5270 ret = update_block_group(trans, root, bytenr, num_bytes, 0);
5255 if (ret) 5271 if (ret) {
5256 goto abort; 5272 btrfs_abort_transaction(trans, extent_root, ret);
5273 goto out;
5274 }
5257 } 5275 }
5258out: 5276out:
5259 btrfs_free_path(path); 5277 btrfs_free_path(path);
5260 return ret; 5278 return ret;
5261
5262abort:
5263 btrfs_abort_transaction(trans, extent_root, ret);
5264 goto out;
5265} 5279}
5266 5280
5267/* 5281/*
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
141 return -ENOMEM; 141 return -ENOMEM;
142 142
143 ret = btrfs_search_slot(trans, root, key, path, 0, 1); 143 ret = btrfs_search_slot(trans, root, key, path, 0, 1);
144 if (ret < 0) 144 if (ret < 0) {
145 goto out_abort; 145 btrfs_abort_transaction(trans, root, ret);
146 goto out;
147 }
146 148
147 if (ret != 0) { 149 if (ret != 0) {
148 btrfs_print_leaf(root, path->nodes[0]); 150 btrfs_print_leaf(root, path->nodes[0]);
@@ -166,16 +168,23 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
166 btrfs_release_path(path); 168 btrfs_release_path(path);
167 ret = btrfs_search_slot(trans, root, key, path, 169 ret = btrfs_search_slot(trans, root, key, path,
168 -1, 1); 170 -1, 1);
169 if (ret < 0) 171 if (ret < 0) {
170 goto out_abort; 172 btrfs_abort_transaction(trans, root, ret);
173 goto out;
174 }
175
171 ret = btrfs_del_item(trans, root, path); 176 ret = btrfs_del_item(trans, root, path);
172 if (ret < 0) 177 if (ret < 0) {
173 goto out_abort; 178 btrfs_abort_transaction(trans, root, ret);
179 goto out;
180 }
174 btrfs_release_path(path); 181 btrfs_release_path(path);
175 ret = btrfs_insert_empty_item(trans, root, path, 182 ret = btrfs_insert_empty_item(trans, root, path,
176 key, sizeof(*item)); 183 key, sizeof(*item));
177 if (ret < 0) 184 if (ret < 0) {
178 goto out_abort; 185 btrfs_abort_transaction(trans, root, ret);
186 goto out;
187 }
179 l = path->nodes[0]; 188 l = path->nodes[0];
180 slot = path->slots[0]; 189 slot = path->slots[0];
181 ptr = btrfs_item_ptr_offset(l, slot); 190 ptr = btrfs_item_ptr_offset(l, slot);
@@ -192,10 +201,6 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
192out: 201out:
193 btrfs_free_path(path); 202 btrfs_free_path(path);
194 return ret; 203 return ret;
195
196out_abort:
197 btrfs_abort_transaction(trans, root, ret);
198 goto out;
199} 204}
200 205
201int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, 206int 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)
1775 1775
1776 if (seeding_dev) { 1776 if (seeding_dev) {
1777 ret = init_first_rw_device(trans, root, device); 1777 ret = init_first_rw_device(trans, root, device);
1778 if (ret) 1778 if (ret) {
1779 btrfs_abort_transaction(trans, root, ret);
1779 goto error_trans; 1780 goto error_trans;
1781 }
1780 ret = btrfs_finish_sprout(trans, root); 1782 ret = btrfs_finish_sprout(trans, root);
1781 if (ret) 1783 if (ret) {
1784 btrfs_abort_transaction(trans, root, ret);
1782 goto error_trans; 1785 goto error_trans;
1786 }
1783 } else { 1787 } else {
1784 ret = btrfs_add_device(trans, root, device); 1788 ret = btrfs_add_device(trans, root, device);
1785 if (ret) 1789 if (ret) {
1790 btrfs_abort_transaction(trans, root, ret);
1786 goto error_trans; 1791 goto error_trans;
1792 }
1787 } 1793 }
1788 1794
1789 /* 1795 /*
@@ -1814,7 +1820,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1814 1820
1815error_trans: 1821error_trans:
1816 unlock_chunks(root); 1822 unlock_chunks(root);
1817 btrfs_abort_transaction(trans, root, ret);
1818 btrfs_end_transaction(trans, root); 1823 btrfs_end_transaction(trans, root);
1819 rcu_string_free(device->name); 1824 rcu_string_free(device->name);
1820 kfree(device); 1825 kfree(device);
@@ -3608,12 +3613,16 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
3608 ret = __btrfs_alloc_chunk(trans, extent_root, &sys_map, 3613 ret = __btrfs_alloc_chunk(trans, extent_root, &sys_map,
3609 &sys_chunk_size, &sys_stripe_size, 3614 &sys_chunk_size, &sys_stripe_size,
3610 sys_chunk_offset, alloc_profile); 3615 sys_chunk_offset, alloc_profile);
3611 if (ret) 3616 if (ret) {
3612 goto abort; 3617 btrfs_abort_transaction(trans, root, ret);
3618 goto out;
3619 }
3613 3620
3614 ret = btrfs_add_device(trans, fs_info->chunk_root, device); 3621 ret = btrfs_add_device(trans, fs_info->chunk_root, device);
3615 if (ret) 3622 if (ret) {
3616 goto abort; 3623 btrfs_abort_transaction(trans, root, ret);
3624 goto out;
3625 }
3617 3626
3618 /* 3627 /*
3619 * Modifying chunk tree needs allocating new blocks from both 3628 * 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,
3623 */ 3632 */
3624 ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset, 3633 ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset,
3625 chunk_size, stripe_size); 3634 chunk_size, stripe_size);
3626 if (ret) 3635 if (ret) {
3627 goto abort; 3636 btrfs_abort_transaction(trans, root, ret);
3637 goto out;
3638 }
3628 3639
3629 ret = __finish_chunk_alloc(trans, extent_root, sys_map, 3640 ret = __finish_chunk_alloc(trans, extent_root, sys_map,
3630 sys_chunk_offset, sys_chunk_size, 3641 sys_chunk_offset, sys_chunk_size,
3631 sys_stripe_size); 3642 sys_stripe_size);
3632 if (ret) 3643 if (ret)
3633 goto abort; 3644 btrfs_abort_transaction(trans, root, ret);
3634 3645
3635 return 0; 3646out:
3636 3647
3637abort:
3638 btrfs_abort_transaction(trans, root, ret);
3639 return ret; 3648 return ret;
3640} 3649}
3641 3650