aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXue jiufei <xuejiufei@huawei.com>2016-03-25 17:21:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-25 19:37:42 -0400
commit1721598985dc3b92bc3ff45ad0c287bd1814417a (patch)
tree1cc79c836fd7e52b863e619c4d6b989998f82147
parente5054c9aefd26ac2401f4b17eda82fab71796dca (diff)
ocfs2: extend transaction for ocfs2_remove_rightmost_path() and ocfs2_update_edge_lengths() before to avoid inconsistency between inode and et
I found that jbd2_journal_restart() is called in some places without keeping things consistently before. However, jbd2_journal_restart() may commit the handle's transaction and restart another one. If the first transaction is committed successfully while another not, it may cause filesystem inconsistency or read only. This is an effort to fix this kind of problems. This patch (of 3): The following functions will be called while truncating an extent: ocfs2_remove_btree_range -> ocfs2_start_trans -> ocfs2_remove_extent -> ocfs2_truncate_rec -> ocfs2_extend_rotate_transaction -> jbd2_journal_restart if jbd2_journal_extend fail -> ocfs2_rotate_tree_left -> ocfs2_remove_rightmost_path -> ocfs2_extend_rotate_transaction -> ocfs2_unlink_subtree -> ocfs2_update_edge_lengths -> ocfs2_extend_trans -> jbd2_journal_restart if jbd2_journal_extend fail -> ocfs2_et_update_clusters -> ocfs2_commit_trans jbd2_journal_restart() may be called and it may happened that the buffers dirtied in ocfs2_truncate_rec() are committed while buffers dirtied in ocfs2_et_update_clusters() are not, the total clusters on extent tree and i_clusters in ocfs2_dinode is inconsistency. So the clusters got from ocfs2_dinode is incorrect, and it also cause read-only problem when call ocfs2_commit_truncate() with the error message: "Inode %llu has empty extent block at %llu". We should extend enough credits for function ocfs2_remove_rightmost_path and ocfs2_update_edge_lengths to avoid this inconsistency. Signed-off-by: joyce.xue <xuejiufei@huawei.com> Acked-by: Joseph Qi <joseph.qi@huawei.com> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ocfs2/alloc.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 1748cea1c9d7..f9ddb5a440a6 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -2516,21 +2516,6 @@ static int ocfs2_update_edge_lengths(handle_t *handle,
2516 struct ocfs2_extent_block *eb; 2516 struct ocfs2_extent_block *eb;
2517 u32 range; 2517 u32 range;
2518 2518
2519 /*
2520 * In normal tree rotation process, we will never touch the
2521 * tree branch above subtree_index and ocfs2_extend_rotate_transaction
2522 * doesn't reserve the credits for them either.
2523 *
2524 * But we do have a special case here which will update the rightmost
2525 * records for all the bh in the path.
2526 * So we have to allocate extra credits and access them.
2527 */
2528 ret = ocfs2_extend_trans(handle, subtree_index);
2529 if (ret) {
2530 mlog_errno(ret);
2531 goto out;
2532 }
2533
2534 ret = ocfs2_journal_access_path(et->et_ci, handle, path); 2519 ret = ocfs2_journal_access_path(et->et_ci, handle, path);
2535 if (ret) { 2520 if (ret) {
2536 mlog_errno(ret); 2521 mlog_errno(ret);
@@ -2956,7 +2941,7 @@ static int __ocfs2_rotate_tree_left(handle_t *handle,
2956 right_path->p_node[subtree_root].bh->b_blocknr, 2941 right_path->p_node[subtree_root].bh->b_blocknr,
2957 right_path->p_tree_depth); 2942 right_path->p_tree_depth);
2958 2943
2959 ret = ocfs2_extend_rotate_transaction(handle, subtree_root, 2944 ret = ocfs2_extend_rotate_transaction(handle, 0,
2960 orig_credits, left_path); 2945 orig_credits, left_path);
2961 if (ret) { 2946 if (ret) {
2962 mlog_errno(ret); 2947 mlog_errno(ret);
@@ -3029,21 +3014,9 @@ static int ocfs2_remove_rightmost_path(handle_t *handle,
3029 struct ocfs2_extent_block *eb; 3014 struct ocfs2_extent_block *eb;
3030 struct ocfs2_extent_list *el; 3015 struct ocfs2_extent_list *el;
3031 3016
3032
3033 ret = ocfs2_et_sanity_check(et); 3017 ret = ocfs2_et_sanity_check(et);
3034 if (ret) 3018 if (ret)
3035 goto out; 3019 goto out;
3036 /*
3037 * There's two ways we handle this depending on
3038 * whether path is the only existing one.
3039 */
3040 ret = ocfs2_extend_rotate_transaction(handle, 0,
3041 handle->h_buffer_credits,
3042 path);
3043 if (ret) {
3044 mlog_errno(ret);
3045 goto out;
3046 }
3047 3020
3048 ret = ocfs2_journal_access_path(et->et_ci, handle, path); 3021 ret = ocfs2_journal_access_path(et->et_ci, handle, path);
3049 if (ret) { 3022 if (ret) {
@@ -3641,6 +3614,14 @@ static int ocfs2_merge_rec_left(struct ocfs2_path *right_path,
3641 */ 3614 */
3642 if (le16_to_cpu(right_rec->e_leaf_clusters) == 0 && 3615 if (le16_to_cpu(right_rec->e_leaf_clusters) == 0 &&
3643 le16_to_cpu(el->l_next_free_rec) == 1) { 3616 le16_to_cpu(el->l_next_free_rec) == 1) {
3617 /* extend credit for ocfs2_remove_rightmost_path */
3618 ret = ocfs2_extend_rotate_transaction(handle, 0,
3619 handle->h_buffer_credits,
3620 right_path);
3621 if (ret) {
3622 mlog_errno(ret);
3623 goto out;
3624 }
3644 3625
3645 ret = ocfs2_remove_rightmost_path(handle, et, 3626 ret = ocfs2_remove_rightmost_path(handle, et,
3646 right_path, 3627 right_path,
@@ -3679,6 +3660,14 @@ static int ocfs2_try_to_merge_extent(handle_t *handle,
3679 BUG_ON(ctxt->c_contig_type == CONTIG_NONE); 3660 BUG_ON(ctxt->c_contig_type == CONTIG_NONE);
3680 3661
3681 if (ctxt->c_split_covers_rec && ctxt->c_has_empty_extent) { 3662 if (ctxt->c_split_covers_rec && ctxt->c_has_empty_extent) {
3663 /* extend credit for ocfs2_remove_rightmost_path */
3664 ret = ocfs2_extend_rotate_transaction(handle, 0,
3665 handle->h_buffer_credits,
3666 path);
3667 if (ret) {
3668 mlog_errno(ret);
3669 goto out;
3670 }
3682 /* 3671 /*
3683 * The merge code will need to create an empty 3672 * The merge code will need to create an empty
3684 * extent to take the place of the newly 3673 * extent to take the place of the newly
@@ -3727,6 +3716,15 @@ static int ocfs2_try_to_merge_extent(handle_t *handle,
3727 */ 3716 */
3728 BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); 3717 BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0]));
3729 3718
3719 /* extend credit for ocfs2_remove_rightmost_path */
3720 ret = ocfs2_extend_rotate_transaction(handle, 0,
3721 handle->h_buffer_credits,
3722 path);
3723 if (ret) {
3724 mlog_errno(ret);
3725 goto out;
3726 }
3727
3730 /* The merge left us with an empty extent, remove it. */ 3728 /* The merge left us with an empty extent, remove it. */
3731 ret = ocfs2_rotate_tree_left(handle, et, path, dealloc); 3729 ret = ocfs2_rotate_tree_left(handle, et, path, dealloc);
3732 if (ret) { 3730 if (ret) {
@@ -3748,6 +3746,15 @@ static int ocfs2_try_to_merge_extent(handle_t *handle,
3748 goto out; 3746 goto out;
3749 } 3747 }
3750 3748
3749 /* extend credit for ocfs2_remove_rightmost_path */
3750 ret = ocfs2_extend_rotate_transaction(handle, 0,
3751 handle->h_buffer_credits,
3752 path);
3753 if (ret) {
3754 mlog_errno(ret);
3755 goto out;
3756 }
3757
3751 ret = ocfs2_rotate_tree_left(handle, et, path, dealloc); 3758 ret = ocfs2_rotate_tree_left(handle, et, path, dealloc);
3752 /* 3759 /*
3753 * Error from this last rotate is not critical, so 3760 * Error from this last rotate is not critical, so
@@ -3783,6 +3790,16 @@ static int ocfs2_try_to_merge_extent(handle_t *handle,
3783 } 3790 }
3784 3791
3785 if (ctxt->c_split_covers_rec) { 3792 if (ctxt->c_split_covers_rec) {
3793 /* extend credit for ocfs2_remove_rightmost_path */
3794 ret = ocfs2_extend_rotate_transaction(handle, 0,
3795 handle->h_buffer_credits,
3796 path);
3797 if (ret) {
3798 mlog_errno(ret);
3799 ret = 0;
3800 goto out;
3801 }
3802
3786 /* 3803 /*
3787 * The merge may have left an empty extent in 3804 * The merge may have left an empty extent in
3788 * our leaf. Try to rotate it away. 3805 * our leaf. Try to rotate it away.
@@ -5342,6 +5359,15 @@ static int ocfs2_truncate_rec(handle_t *handle,
5342 struct ocfs2_extent_block *eb; 5359 struct ocfs2_extent_block *eb;
5343 5360
5344 if (ocfs2_is_empty_extent(&el->l_recs[0]) && index > 0) { 5361 if (ocfs2_is_empty_extent(&el->l_recs[0]) && index > 0) {
5362 /* extend credit for ocfs2_remove_rightmost_path */
5363 ret = ocfs2_extend_rotate_transaction(handle, 0,
5364 handle->h_buffer_credits,
5365 path);
5366 if (ret) {
5367 mlog_errno(ret);
5368 goto out;
5369 }
5370
5345 ret = ocfs2_rotate_tree_left(handle, et, path, dealloc); 5371 ret = ocfs2_rotate_tree_left(handle, et, path, dealloc);
5346 if (ret) { 5372 if (ret) {
5347 mlog_errno(ret); 5373 mlog_errno(ret);