aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTsutomu Itoh <t-itoh@jp.fujitsu.com>2011-01-24 21:51:38 -0500
committerChris Mason <chris.mason@oracle.com>2011-01-28 16:40:37 -0500
commit3612b49598c303cfb22a4b609427f829828e2427 (patch)
treed0e9eabb176777ab80af5d78eab0555044172370 /fs
parent34d19bada00f4825588b338a8ee193820f9ceeb0 (diff)
btrfs: fix return value check of btrfs_join_transaction()
The error check of btrfs_join_transaction()/btrfs_join_transaction_nolock() is added, and the mistake of the error check in several places is corrected. For more stable Btrfs, I think that we should reduce BUG_ON(). But, I think that long time is necessary for this. So, I propose this patch as a short-term solution. With this patch: - To more stable Btrfs, the part that should be corrected is clarified. - The panic isn't done by the NULL pointer reference etc. (even if BUG_ON() is increased temporarily) - The error code is returned in the place where the error can be easily returned. As a long-term plan: - BUG_ON() is reduced by using the forced-readonly framework, etc. Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/disk-io.c5
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/inode.c24
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/relocation.c26
-rw-r--r--fs/btrfs/transaction.c5
6 files changed, 51 insertions, 13 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2887b8be6fdd..b36eeef19194 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1550,6 +1550,7 @@ static int transaction_kthread(void *arg)
1550 spin_unlock(&root->fs_info->new_trans_lock); 1550 spin_unlock(&root->fs_info->new_trans_lock);
1551 1551
1552 trans = btrfs_join_transaction(root, 1); 1552 trans = btrfs_join_transaction(root, 1);
1553 BUG_ON(IS_ERR(trans));
1553 if (transid == trans->transid) { 1554 if (transid == trans->transid) {
1554 ret = btrfs_commit_transaction(trans, root); 1555 ret = btrfs_commit_transaction(trans, root);
1555 BUG_ON(ret); 1556 BUG_ON(ret);
@@ -2464,10 +2465,14 @@ int btrfs_commit_super(struct btrfs_root *root)
2464 up_write(&root->fs_info->cleanup_work_sem); 2465 up_write(&root->fs_info->cleanup_work_sem);
2465 2466
2466 trans = btrfs_join_transaction(root, 1); 2467 trans = btrfs_join_transaction(root, 1);
2468 if (IS_ERR(trans))
2469 return PTR_ERR(trans);
2467 ret = btrfs_commit_transaction(trans, root); 2470 ret = btrfs_commit_transaction(trans, root);
2468 BUG_ON(ret); 2471 BUG_ON(ret);
2469 /* run commit again to drop the original snapshot */ 2472 /* run commit again to drop the original snapshot */
2470 trans = btrfs_join_transaction(root, 1); 2473 trans = btrfs_join_transaction(root, 1);
2474 if (IS_ERR(trans))
2475 return PTR_ERR(trans);
2471 btrfs_commit_transaction(trans, root); 2476 btrfs_commit_transaction(trans, root);
2472 ret = btrfs_write_and_wait_transaction(NULL, root); 2477 ret = btrfs_write_and_wait_transaction(NULL, root);
2473 BUG_ON(ret); 2478 BUG_ON(ret);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index bcf303204f7f..98ee139885cc 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -7478,7 +7478,7 @@ int btrfs_drop_dead_reloc_roots(struct btrfs_root *root)
7478 BUG_ON(reloc_root->commit_root != NULL); 7478 BUG_ON(reloc_root->commit_root != NULL);
7479 while (1) { 7479 while (1) {
7480 trans = btrfs_join_transaction(root, 1); 7480 trans = btrfs_join_transaction(root, 1);
7481 BUG_ON(!trans); 7481 BUG_ON(IS_ERR(trans));
7482 7482
7483 mutex_lock(&root->fs_info->drop_mutex); 7483 mutex_lock(&root->fs_info->drop_mutex);
7484 ret = btrfs_drop_snapshot(trans, reloc_root); 7484 ret = btrfs_drop_snapshot(trans, reloc_root);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2b7d251d6ad1..40fee137dd11 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -416,7 +416,7 @@ again:
416 } 416 }
417 if (start == 0) { 417 if (start == 0) {
418 trans = btrfs_join_transaction(root, 1); 418 trans = btrfs_join_transaction(root, 1);
419 BUG_ON(!trans); 419 BUG_ON(IS_ERR(trans));
420 btrfs_set_trans_block_group(trans, inode); 420 btrfs_set_trans_block_group(trans, inode);
421 trans->block_rsv = &root->fs_info->delalloc_block_rsv; 421 trans->block_rsv = &root->fs_info->delalloc_block_rsv;
422 422
@@ -612,6 +612,7 @@ retry:
612 GFP_NOFS); 612 GFP_NOFS);
613 613
614 trans = btrfs_join_transaction(root, 1); 614 trans = btrfs_join_transaction(root, 1);
615 BUG_ON(IS_ERR(trans));
615 ret = btrfs_reserve_extent(trans, root, 616 ret = btrfs_reserve_extent(trans, root,
616 async_extent->compressed_size, 617 async_extent->compressed_size,
617 async_extent->compressed_size, 618 async_extent->compressed_size,
@@ -771,7 +772,7 @@ static noinline int cow_file_range(struct inode *inode,
771 772
772 BUG_ON(root == root->fs_info->tree_root); 773 BUG_ON(root == root->fs_info->tree_root);
773 trans = btrfs_join_transaction(root, 1); 774 trans = btrfs_join_transaction(root, 1);
774 BUG_ON(!trans); 775 BUG_ON(IS_ERR(trans));
775 btrfs_set_trans_block_group(trans, inode); 776 btrfs_set_trans_block_group(trans, inode);
776 trans->block_rsv = &root->fs_info->delalloc_block_rsv; 777 trans->block_rsv = &root->fs_info->delalloc_block_rsv;
777 778
@@ -1049,7 +1050,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1049 } else { 1050 } else {
1050 trans = btrfs_join_transaction(root, 1); 1051 trans = btrfs_join_transaction(root, 1);
1051 } 1052 }
1052 BUG_ON(!trans); 1053 BUG_ON(IS_ERR(trans));
1053 1054
1054 cow_start = (u64)-1; 1055 cow_start = (u64)-1;
1055 cur_offset = start; 1056 cur_offset = start;
@@ -1704,7 +1705,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1704 trans = btrfs_join_transaction_nolock(root, 1); 1705 trans = btrfs_join_transaction_nolock(root, 1);
1705 else 1706 else
1706 trans = btrfs_join_transaction(root, 1); 1707 trans = btrfs_join_transaction(root, 1);
1707 BUG_ON(!trans); 1708 BUG_ON(IS_ERR(trans));
1708 btrfs_set_trans_block_group(trans, inode); 1709 btrfs_set_trans_block_group(trans, inode);
1709 trans->block_rsv = &root->fs_info->delalloc_block_rsv; 1710 trans->block_rsv = &root->fs_info->delalloc_block_rsv;
1710 ret = btrfs_update_inode(trans, root, inode); 1711 ret = btrfs_update_inode(trans, root, inode);
@@ -1721,6 +1722,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1721 trans = btrfs_join_transaction_nolock(root, 1); 1722 trans = btrfs_join_transaction_nolock(root, 1);
1722 else 1723 else
1723 trans = btrfs_join_transaction(root, 1); 1724 trans = btrfs_join_transaction(root, 1);
1725 BUG_ON(IS_ERR(trans));
1724 btrfs_set_trans_block_group(trans, inode); 1726 btrfs_set_trans_block_group(trans, inode);
1725 trans->block_rsv = &root->fs_info->delalloc_block_rsv; 1727 trans->block_rsv = &root->fs_info->delalloc_block_rsv;
1726 1728
@@ -2382,6 +2384,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
2382 2384
2383 if (root->orphan_block_rsv || root->orphan_item_inserted) { 2385 if (root->orphan_block_rsv || root->orphan_item_inserted) {
2384 trans = btrfs_join_transaction(root, 1); 2386 trans = btrfs_join_transaction(root, 1);
2387 BUG_ON(IS_ERR(trans));
2385 btrfs_end_transaction(trans, root); 2388 btrfs_end_transaction(trans, root);
2386 } 2389 }
2387 2390
@@ -4350,6 +4353,8 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
4350 trans = btrfs_join_transaction_nolock(root, 1); 4353 trans = btrfs_join_transaction_nolock(root, 1);
4351 else 4354 else
4352 trans = btrfs_join_transaction(root, 1); 4355 trans = btrfs_join_transaction(root, 1);
4356 if (IS_ERR(trans))
4357 return PTR_ERR(trans);
4353 btrfs_set_trans_block_group(trans, inode); 4358 btrfs_set_trans_block_group(trans, inode);
4354 if (nolock) 4359 if (nolock)
4355 ret = btrfs_end_transaction_nolock(trans, root); 4360 ret = btrfs_end_transaction_nolock(trans, root);
@@ -4375,6 +4380,7 @@ void btrfs_dirty_inode(struct inode *inode)
4375 return; 4380 return;
4376 4381
4377 trans = btrfs_join_transaction(root, 1); 4382 trans = btrfs_join_transaction(root, 1);
4383 BUG_ON(IS_ERR(trans));
4378 btrfs_set_trans_block_group(trans, inode); 4384 btrfs_set_trans_block_group(trans, inode);
4379 4385
4380 ret = btrfs_update_inode(trans, root, inode); 4386 ret = btrfs_update_inode(trans, root, inode);
@@ -5179,6 +5185,8 @@ again:
5179 em = NULL; 5185 em = NULL;
5180 btrfs_release_path(root, path); 5186 btrfs_release_path(root, path);
5181 trans = btrfs_join_transaction(root, 1); 5187 trans = btrfs_join_transaction(root, 1);
5188 if (IS_ERR(trans))
5189 return ERR_CAST(trans);
5182 goto again; 5190 goto again;
5183 } 5191 }
5184 map = kmap(page); 5192 map = kmap(page);
@@ -5283,8 +5291,8 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
5283 btrfs_drop_extent_cache(inode, start, start + len - 1, 0); 5291 btrfs_drop_extent_cache(inode, start, start + len - 1, 0);
5284 5292
5285 trans = btrfs_join_transaction(root, 0); 5293 trans = btrfs_join_transaction(root, 0);
5286 if (!trans) 5294 if (IS_ERR(trans))
5287 return ERR_PTR(-ENOMEM); 5295 return ERR_CAST(trans);
5288 5296
5289 trans->block_rsv = &root->fs_info->delalloc_block_rsv; 5297 trans->block_rsv = &root->fs_info->delalloc_block_rsv;
5290 5298
@@ -5508,7 +5516,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
5508 * while we look for nocow cross refs 5516 * while we look for nocow cross refs
5509 */ 5517 */
5510 trans = btrfs_join_transaction(root, 0); 5518 trans = btrfs_join_transaction(root, 0);
5511 if (!trans) 5519 if (IS_ERR(trans))
5512 goto must_cow; 5520 goto must_cow;
5513 5521
5514 if (can_nocow_odirect(trans, inode, start, len) == 1) { 5522 if (can_nocow_odirect(trans, inode, start, len) == 1) {
@@ -5643,7 +5651,7 @@ again:
5643 BUG_ON(!ordered); 5651 BUG_ON(!ordered);
5644 5652
5645 trans = btrfs_join_transaction(root, 1); 5653 trans = btrfs_join_transaction(root, 1);
5646 if (!trans) { 5654 if (IS_ERR(trans)) {
5647 err = -ENOMEM; 5655 err = -ENOMEM;
5648 goto out; 5656 goto out;
5649 } 5657 }
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index edd82becbb9e..04b4fb9144a9 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -203,7 +203,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
203 203
204 204
205 trans = btrfs_join_transaction(root, 1); 205 trans = btrfs_join_transaction(root, 1);
206 BUG_ON(!trans); 206 BUG_ON(IS_ERR(trans));
207 207
208 ret = btrfs_update_inode(trans, root, inode); 208 ret = btrfs_update_inode(trans, root, inode);
209 BUG_ON(ret); 209 BUG_ON(ret);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 045c9c2b2d7e..ea9965430241 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2147,6 +2147,12 @@ again:
2147 } 2147 }
2148 2148
2149 trans = btrfs_join_transaction(rc->extent_root, 1); 2149 trans = btrfs_join_transaction(rc->extent_root, 1);
2150 if (IS_ERR(trans)) {
2151 if (!err)
2152 btrfs_block_rsv_release(rc->extent_root,
2153 rc->block_rsv, num_bytes);
2154 return PTR_ERR(trans);
2155 }
2150 2156
2151 if (!err) { 2157 if (!err) {
2152 if (num_bytes != rc->merging_rsv_size) { 2158 if (num_bytes != rc->merging_rsv_size) {
@@ -3222,6 +3228,7 @@ truncate:
3222 trans = btrfs_join_transaction(root, 0); 3228 trans = btrfs_join_transaction(root, 0);
3223 if (IS_ERR(trans)) { 3229 if (IS_ERR(trans)) {
3224 btrfs_free_path(path); 3230 btrfs_free_path(path);
3231 ret = PTR_ERR(trans);
3225 goto out; 3232 goto out;
3226 } 3233 }
3227 3234
@@ -3628,6 +3635,7 @@ int prepare_to_relocate(struct reloc_control *rc)
3628 set_reloc_control(rc); 3635 set_reloc_control(rc);
3629 3636
3630 trans = btrfs_join_transaction(rc->extent_root, 1); 3637 trans = btrfs_join_transaction(rc->extent_root, 1);
3638 BUG_ON(IS_ERR(trans));
3631 btrfs_commit_transaction(trans, rc->extent_root); 3639 btrfs_commit_transaction(trans, rc->extent_root);
3632 return 0; 3640 return 0;
3633} 3641}
@@ -3804,7 +3812,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3804 3812
3805 /* get rid of pinned extents */ 3813 /* get rid of pinned extents */
3806 trans = btrfs_join_transaction(rc->extent_root, 1); 3814 trans = btrfs_join_transaction(rc->extent_root, 1);
3807 btrfs_commit_transaction(trans, rc->extent_root); 3815 if (IS_ERR(trans))
3816 err = PTR_ERR(trans);
3817 else
3818 btrfs_commit_transaction(trans, rc->extent_root);
3808out_free: 3819out_free:
3809 btrfs_free_block_rsv(rc->extent_root, rc->block_rsv); 3820 btrfs_free_block_rsv(rc->extent_root, rc->block_rsv);
3810 btrfs_free_path(path); 3821 btrfs_free_path(path);
@@ -4125,6 +4136,11 @@ int btrfs_recover_relocation(struct btrfs_root *root)
4125 set_reloc_control(rc); 4136 set_reloc_control(rc);
4126 4137
4127 trans = btrfs_join_transaction(rc->extent_root, 1); 4138 trans = btrfs_join_transaction(rc->extent_root, 1);
4139 if (IS_ERR(trans)) {
4140 unset_reloc_control(rc);
4141 err = PTR_ERR(trans);
4142 goto out_free;
4143 }
4128 4144
4129 rc->merge_reloc_tree = 1; 4145 rc->merge_reloc_tree = 1;
4130 4146
@@ -4154,9 +4170,13 @@ int btrfs_recover_relocation(struct btrfs_root *root)
4154 unset_reloc_control(rc); 4170 unset_reloc_control(rc);
4155 4171
4156 trans = btrfs_join_transaction(rc->extent_root, 1); 4172 trans = btrfs_join_transaction(rc->extent_root, 1);
4157 btrfs_commit_transaction(trans, rc->extent_root); 4173 if (IS_ERR(trans))
4158out: 4174 err = PTR_ERR(trans);
4175 else
4176 btrfs_commit_transaction(trans, rc->extent_root);
4177out_free:
4159 kfree(rc); 4178 kfree(rc);
4179out:
4160 while (!list_empty(&reloc_roots)) { 4180 while (!list_empty(&reloc_roots)) {
4161 reloc_root = list_entry(reloc_roots.next, 4181 reloc_root = list_entry(reloc_roots.next,
4162 struct btrfs_root, root_list); 4182 struct btrfs_root, root_list);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index bae5c7b8bbe2..3d73c8d93bbb 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1161,6 +1161,11 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
1161 INIT_DELAYED_WORK(&ac->work, do_async_commit); 1161 INIT_DELAYED_WORK(&ac->work, do_async_commit);
1162 ac->root = root; 1162 ac->root = root;
1163 ac->newtrans = btrfs_join_transaction(root, 0); 1163 ac->newtrans = btrfs_join_transaction(root, 0);
1164 if (IS_ERR(ac->newtrans)) {
1165 int err = PTR_ERR(ac->newtrans);
1166 kfree(ac);
1167 return err;
1168 }
1164 1169
1165 /* take transaction reference */ 1170 /* take transaction reference */
1166 mutex_lock(&root->fs_info->trans_mutex); 1171 mutex_lock(&root->fs_info->trans_mutex);