diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/alloc.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 9edcde4974aa..11085af71247 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -2476,15 +2476,37 @@ out_ret_path: | |||
2476 | return ret; | 2476 | return ret; |
2477 | } | 2477 | } |
2478 | 2478 | ||
2479 | static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle, | 2479 | static int ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle, |
2480 | struct ocfs2_path *path) | 2480 | int subtree_index, struct ocfs2_path *path) |
2481 | { | 2481 | { |
2482 | int i, idx; | 2482 | int i, idx, ret; |
2483 | struct ocfs2_extent_rec *rec; | 2483 | struct ocfs2_extent_rec *rec; |
2484 | struct ocfs2_extent_list *el; | 2484 | struct ocfs2_extent_list *el; |
2485 | struct ocfs2_extent_block *eb; | 2485 | struct ocfs2_extent_block *eb; |
2486 | u32 range; | 2486 | u32 range; |
2487 | 2487 | ||
2488 | /* | ||
2489 | * In normal tree rotation process, we will never touch the | ||
2490 | * tree branch above subtree_index and ocfs2_extend_rotate_transaction | ||
2491 | * doesn't reserve the credits for them either. | ||
2492 | * | ||
2493 | * But we do have a special case here which will update the rightmost | ||
2494 | * records for all the bh in the path. | ||
2495 | * So we have to allocate extra credits and access them. | ||
2496 | */ | ||
2497 | ret = ocfs2_extend_trans(handle, | ||
2498 | handle->h_buffer_credits + subtree_index); | ||
2499 | if (ret) { | ||
2500 | mlog_errno(ret); | ||
2501 | goto out; | ||
2502 | } | ||
2503 | |||
2504 | ret = ocfs2_journal_access_path(inode, handle, path); | ||
2505 | if (ret) { | ||
2506 | mlog_errno(ret); | ||
2507 | goto out; | ||
2508 | } | ||
2509 | |||
2488 | /* Path should always be rightmost. */ | 2510 | /* Path should always be rightmost. */ |
2489 | eb = (struct ocfs2_extent_block *)path_leaf_bh(path)->b_data; | 2511 | eb = (struct ocfs2_extent_block *)path_leaf_bh(path)->b_data; |
2490 | BUG_ON(eb->h_next_leaf_blk != 0ULL); | 2512 | BUG_ON(eb->h_next_leaf_blk != 0ULL); |
@@ -2505,6 +2527,8 @@ static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle, | |||
2505 | 2527 | ||
2506 | ocfs2_journal_dirty(handle, path->p_node[i].bh); | 2528 | ocfs2_journal_dirty(handle, path->p_node[i].bh); |
2507 | } | 2529 | } |
2530 | out: | ||
2531 | return ret; | ||
2508 | } | 2532 | } |
2509 | 2533 | ||
2510 | static void ocfs2_unlink_path(struct inode *inode, handle_t *handle, | 2534 | static void ocfs2_unlink_path(struct inode *inode, handle_t *handle, |
@@ -2717,7 +2741,12 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle, | |||
2717 | if (del_right_subtree) { | 2741 | if (del_right_subtree) { |
2718 | ocfs2_unlink_subtree(inode, handle, left_path, right_path, | 2742 | ocfs2_unlink_subtree(inode, handle, left_path, right_path, |
2719 | subtree_index, dealloc); | 2743 | subtree_index, dealloc); |
2720 | ocfs2_update_edge_lengths(inode, handle, left_path); | 2744 | ret = ocfs2_update_edge_lengths(inode, handle, subtree_index, |
2745 | left_path); | ||
2746 | if (ret) { | ||
2747 | mlog_errno(ret); | ||
2748 | goto out; | ||
2749 | } | ||
2721 | 2750 | ||
2722 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; | 2751 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; |
2723 | ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); | 2752 | ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); |
@@ -3034,7 +3063,12 @@ static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle, | |||
3034 | 3063 | ||
3035 | ocfs2_unlink_subtree(inode, handle, left_path, path, | 3064 | ocfs2_unlink_subtree(inode, handle, left_path, path, |
3036 | subtree_index, dealloc); | 3065 | subtree_index, dealloc); |
3037 | ocfs2_update_edge_lengths(inode, handle, left_path); | 3066 | ret = ocfs2_update_edge_lengths(inode, handle, subtree_index, |
3067 | left_path); | ||
3068 | if (ret) { | ||
3069 | mlog_errno(ret); | ||
3070 | goto out; | ||
3071 | } | ||
3038 | 3072 | ||
3039 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; | 3073 | eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data; |
3040 | ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); | 3074 | ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno)); |