aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-07-21 03:42:05 -0400
committerJoel Becker <joel.becker@oracle.com>2009-07-21 17:41:54 -0400
commit3c5e10683e684ef45614c9071847e48f633d9806 (patch)
tree2861ea95385422c50afc818dd6bb2d2c6cb9d46a
parent1f4cea3790bf44137192f441ee84af256e3bf809 (diff)
ocfs2: Add extra credits and access the modified bh in update_edge_lengths.
In normal tree rotation left process, we will never touch the tree branch above subtree_index and ocfs2_extend_rotate_transaction doesn't reserve the credits for them either. But when we want to delete the rightmost extent block, we have to update the rightmost records for all the rightmost branch(See ocfs2_update_edge_lengths), so we have to allocate extra credits for them. What's more, we have to access them also. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--fs/ocfs2/alloc.c44
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
2479static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle, 2479static 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 }
2530out:
2531 return ret;
2508} 2532}
2509 2533
2510static void ocfs2_unlink_path(struct inode *inode, handle_t *handle, 2534static 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));