aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
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