diff options
author | Tsutomu Itoh <t-itoh@jp.fujitsu.com> | 2011-01-24 21:51:38 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-01-28 16:40:37 -0500 |
commit | 3612b49598c303cfb22a4b609427f829828e2427 (patch) | |
tree | d0e9eabb176777ab80af5d78eab0555044172370 /fs/btrfs | |
parent | 34d19bada00f4825588b338a8ee193820f9ceeb0 (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/btrfs')
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 24 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 26 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 5 |
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); | ||
3808 | out_free: | 3819 | out_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)) |
4158 | out: | 4174 | err = PTR_ERR(trans); |
4175 | else | ||
4176 | btrfs_commit_transaction(trans, rc->extent_root); | ||
4177 | out_free: | ||
4159 | kfree(rc); | 4178 | kfree(rc); |
4179 | out: | ||
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); |