diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-01-30 01:21:05 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-04-18 11:56:10 -0400 |
commit | 677b975282e48d1818df4181336307377d56b04e (patch) | |
tree | eb4014d515d3dd23bf70d9cace666f2c85864141 /fs/ocfs2 | |
parent | 52f7c21b613f80cb425d115c9e5b4ed958a133c0 (diff) |
ocfs2: Add support for cross extent block
In ocfs2_merge_rec_left, when we find the merge extent is "CONTIG_RIGHT"
with the first extent record of the next extent block, we will merge it to
the next extent block and change all the related extent blocks accordingly.
In ocfs2_merge_rec_right, when we find the merge extent is "CONTIG_LEFT"
with the last extent record of the previous extent block, we will merge
it to the prevoius extent block and change all the related extent blocks
accordingly.
As for CONTIG_LEFTRIGHT, we will handle CONTIG_RIGHT first so that when
the index is zero, the merge process will be more efficient and easier.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/alloc.c | 366 |
1 files changed, 325 insertions, 41 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 447206eb5c2e..f63cb32e224d 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -1450,6 +1450,8 @@ static void ocfs2_adjust_root_records(struct ocfs2_extent_list *root_el, | |||
1450 | * - When our insert into the right path leaf is at the leftmost edge | 1450 | * - When our insert into the right path leaf is at the leftmost edge |
1451 | * and requires an update of the path immediately to it's left. This | 1451 | * and requires an update of the path immediately to it's left. This |
1452 | * can occur at the end of some types of rotation and appending inserts. | 1452 | * can occur at the end of some types of rotation and appending inserts. |
1453 | * - When we've adjusted the last extent record in the left path leaf and the | ||
1454 | * 1st extent record in the right path leaf during cross extent block merge. | ||
1453 | */ | 1455 | */ |
1454 | static void ocfs2_complete_edge_insert(struct inode *inode, handle_t *handle, | 1456 | static void ocfs2_complete_edge_insert(struct inode *inode, handle_t *handle, |
1455 | struct ocfs2_path *left_path, | 1457 | struct ocfs2_path *left_path, |
@@ -2712,24 +2714,147 @@ static void ocfs2_cleanup_merge(struct ocfs2_extent_list *el, | |||
2712 | } | 2714 | } |
2713 | } | 2715 | } |
2714 | 2716 | ||
2717 | static int ocfs2_get_right_path(struct inode *inode, | ||
2718 | struct ocfs2_path *left_path, | ||
2719 | struct ocfs2_path **ret_right_path) | ||
2720 | { | ||
2721 | int ret; | ||
2722 | u32 right_cpos; | ||
2723 | struct ocfs2_path *right_path = NULL; | ||
2724 | struct ocfs2_extent_list *left_el; | ||
2725 | |||
2726 | *ret_right_path = NULL; | ||
2727 | |||
2728 | /* This function shouldn't be called for non-trees. */ | ||
2729 | BUG_ON(left_path->p_tree_depth == 0); | ||
2730 | |||
2731 | left_el = path_leaf_el(left_path); | ||
2732 | BUG_ON(left_el->l_next_free_rec != left_el->l_count); | ||
2733 | |||
2734 | ret = ocfs2_find_cpos_for_right_leaf(inode->i_sb, left_path, | ||
2735 | &right_cpos); | ||
2736 | if (ret) { | ||
2737 | mlog_errno(ret); | ||
2738 | goto out; | ||
2739 | } | ||
2740 | |||
2741 | /* This function shouldn't be called for the rightmost leaf. */ | ||
2742 | BUG_ON(right_cpos == 0); | ||
2743 | |||
2744 | right_path = ocfs2_new_path(path_root_bh(left_path), | ||
2745 | path_root_el(left_path)); | ||
2746 | if (!right_path) { | ||
2747 | ret = -ENOMEM; | ||
2748 | mlog_errno(ret); | ||
2749 | goto out; | ||
2750 | } | ||
2751 | |||
2752 | ret = ocfs2_find_path(inode, right_path, right_cpos); | ||
2753 | if (ret) { | ||
2754 | mlog_errno(ret); | ||
2755 | goto out; | ||
2756 | } | ||
2757 | |||
2758 | *ret_right_path = right_path; | ||
2759 | out: | ||
2760 | if (ret) | ||
2761 | ocfs2_free_path(right_path); | ||
2762 | return ret; | ||
2763 | } | ||
2764 | |||
2715 | /* | 2765 | /* |
2716 | * Remove split_rec clusters from the record at index and merge them | 2766 | * Remove split_rec clusters from the record at index and merge them |
2717 | * onto the beginning of the record at index + 1. | 2767 | * onto the beginning of the record "next" to it. |
2768 | * For index < l_count - 1, the next means the extent rec at index + 1. | ||
2769 | * For index == l_count - 1, the "next" means the 1st extent rec of the | ||
2770 | * next extent block. | ||
2718 | */ | 2771 | */ |
2719 | static int ocfs2_merge_rec_right(struct inode *inode, struct buffer_head *bh, | 2772 | static int ocfs2_merge_rec_right(struct inode *inode, |
2720 | handle_t *handle, | 2773 | struct ocfs2_path *left_path, |
2721 | struct ocfs2_extent_rec *split_rec, | 2774 | handle_t *handle, |
2722 | struct ocfs2_extent_list *el, int index) | 2775 | struct ocfs2_extent_rec *split_rec, |
2776 | int index) | ||
2723 | { | 2777 | { |
2724 | int ret; | 2778 | int ret, next_free, i; |
2725 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); | 2779 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); |
2726 | struct ocfs2_extent_rec *left_rec; | 2780 | struct ocfs2_extent_rec *left_rec; |
2727 | struct ocfs2_extent_rec *right_rec; | 2781 | struct ocfs2_extent_rec *right_rec; |
2782 | struct ocfs2_extent_list *right_el; | ||
2783 | struct ocfs2_path *right_path = NULL; | ||
2784 | int subtree_index = 0; | ||
2785 | struct ocfs2_extent_list *el = path_leaf_el(left_path); | ||
2786 | struct buffer_head *bh = path_leaf_bh(left_path); | ||
2787 | struct buffer_head *root_bh = NULL; | ||
2728 | 2788 | ||
2729 | BUG_ON(index >= le16_to_cpu(el->l_next_free_rec)); | 2789 | BUG_ON(index >= le16_to_cpu(el->l_next_free_rec)); |
2730 | |||
2731 | left_rec = &el->l_recs[index]; | 2790 | left_rec = &el->l_recs[index]; |
2732 | right_rec = &el->l_recs[index + 1]; | 2791 | |
2792 | if (index == le16_to_cpu(el->l_next_free_rec - 1) && | ||
2793 | le16_to_cpu(el->l_next_free_rec) == le16_to_cpu(el->l_count)) { | ||
2794 | /* we meet with a cross extent block merge. */ | ||
2795 | ret = ocfs2_get_right_path(inode, left_path, &right_path); | ||
2796 | if (ret) { | ||
2797 | mlog_errno(ret); | ||
2798 | goto out; | ||
2799 | } | ||
2800 | |||
2801 | right_el = path_leaf_el(right_path); | ||
2802 | next_free = le16_to_cpu(right_el->l_next_free_rec); | ||
2803 | BUG_ON(next_free <= 0); | ||
2804 | right_rec = &right_el->l_recs[0]; | ||
2805 | if (ocfs2_is_empty_extent(right_rec)) { | ||
2806 | BUG_ON(le16_to_cpu(next_free) <= 1); | ||
2807 | right_rec = &right_el->l_recs[1]; | ||
2808 | } | ||
2809 | |||
2810 | BUG_ON(le32_to_cpu(left_rec->e_cpos) + | ||
2811 | le16_to_cpu(left_rec->e_leaf_clusters) != | ||
2812 | le32_to_cpu(right_rec->e_cpos)); | ||
2813 | |||
2814 | subtree_index = ocfs2_find_subtree_root(inode, | ||
2815 | left_path, right_path); | ||
2816 | |||
2817 | ret = ocfs2_extend_rotate_transaction(handle, subtree_index, | ||
2818 | handle->h_buffer_credits, | ||
2819 | right_path); | ||
2820 | if (ret) { | ||
2821 | mlog_errno(ret); | ||
2822 | goto out; | ||
2823 | } | ||
2824 | |||
2825 | root_bh = left_path->p_node[subtree_index].bh; | ||
2826 | BUG_ON(root_bh != right_path->p_node[subtree_index].bh); | ||
2827 | |||
2828 | ret = ocfs2_journal_access(handle, inode, root_bh, | ||
2829 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
2830 | if (ret) { | ||
2831 | mlog_errno(ret); | ||
2832 | goto out; | ||
2833 | } | ||
2834 | |||
2835 | for (i = subtree_index + 1; | ||
2836 | i < path_num_items(right_path); i++) { | ||
2837 | ret = ocfs2_journal_access(handle, inode, | ||
2838 | right_path->p_node[i].bh, | ||
2839 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
2840 | if (ret) { | ||
2841 | mlog_errno(ret); | ||
2842 | goto out; | ||
2843 | } | ||
2844 | |||
2845 | ret = ocfs2_journal_access(handle, inode, | ||
2846 | left_path->p_node[i].bh, | ||
2847 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
2848 | if (ret) { | ||
2849 | mlog_errno(ret); | ||
2850 | goto out; | ||
2851 | } | ||
2852 | } | ||
2853 | |||
2854 | } else { | ||
2855 | BUG_ON(index == le16_to_cpu(el->l_next_free_rec) - 1); | ||
2856 | right_rec = &el->l_recs[index + 1]; | ||
2857 | } | ||
2733 | 2858 | ||
2734 | ret = ocfs2_journal_access(handle, inode, bh, | 2859 | ret = ocfs2_journal_access(handle, inode, bh, |
2735 | OCFS2_JOURNAL_ACCESS_WRITE); | 2860 | OCFS2_JOURNAL_ACCESS_WRITE); |
@@ -2751,30 +2876,156 @@ static int ocfs2_merge_rec_right(struct inode *inode, struct buffer_head *bh, | |||
2751 | if (ret) | 2876 | if (ret) |
2752 | mlog_errno(ret); | 2877 | mlog_errno(ret); |
2753 | 2878 | ||
2879 | if (right_path) { | ||
2880 | ret = ocfs2_journal_dirty(handle, path_leaf_bh(right_path)); | ||
2881 | if (ret) | ||
2882 | mlog_errno(ret); | ||
2883 | |||
2884 | ocfs2_complete_edge_insert(inode, handle, left_path, | ||
2885 | right_path, subtree_index); | ||
2886 | } | ||
2887 | out: | ||
2888 | if (right_path) | ||
2889 | ocfs2_free_path(right_path); | ||
2890 | return ret; | ||
2891 | } | ||
2892 | |||
2893 | static int ocfs2_get_left_path(struct inode *inode, | ||
2894 | struct ocfs2_path *right_path, | ||
2895 | struct ocfs2_path **ret_left_path) | ||
2896 | { | ||
2897 | int ret; | ||
2898 | u32 left_cpos; | ||
2899 | struct ocfs2_path *left_path = NULL; | ||
2900 | |||
2901 | *ret_left_path = NULL; | ||
2902 | |||
2903 | /* This function shouldn't be called for non-trees. */ | ||
2904 | BUG_ON(right_path->p_tree_depth == 0); | ||
2905 | |||
2906 | ret = ocfs2_find_cpos_for_left_leaf(inode->i_sb, | ||
2907 | right_path, &left_cpos); | ||
2908 | if (ret) { | ||
2909 | mlog_errno(ret); | ||
2910 | goto out; | ||
2911 | } | ||
2912 | |||
2913 | /* This function shouldn't be called for the leftmost leaf. */ | ||
2914 | BUG_ON(left_cpos == 0); | ||
2915 | |||
2916 | left_path = ocfs2_new_path(path_root_bh(right_path), | ||
2917 | path_root_el(right_path)); | ||
2918 | if (!left_path) { | ||
2919 | ret = -ENOMEM; | ||
2920 | mlog_errno(ret); | ||
2921 | goto out; | ||
2922 | } | ||
2923 | |||
2924 | ret = ocfs2_find_path(inode, left_path, left_cpos); | ||
2925 | if (ret) { | ||
2926 | mlog_errno(ret); | ||
2927 | goto out; | ||
2928 | } | ||
2929 | |||
2930 | *ret_left_path = left_path; | ||
2754 | out: | 2931 | out: |
2932 | if (ret) | ||
2933 | ocfs2_free_path(left_path); | ||
2755 | return ret; | 2934 | return ret; |
2756 | } | 2935 | } |
2757 | 2936 | ||
2758 | /* | 2937 | /* |
2759 | * Remove split_rec clusters from the record at index and merge them | 2938 | * Remove split_rec clusters from the record at index and merge them |
2760 | * onto the tail of the record at index - 1. | 2939 | * onto the tail of the record "before" it. |
2940 | * For index > 0, the "before" means the extent rec at index - 1. | ||
2941 | * | ||
2942 | * For index == 0, the "before" means the last record of the previous | ||
2943 | * extent block. And there is also a situation that we may need to | ||
2944 | * remove the rightmost leaf extent block in the right_path and change | ||
2945 | * the right path to indicate the new rightmost path. | ||
2761 | */ | 2946 | */ |
2762 | static int ocfs2_merge_rec_left(struct inode *inode, struct buffer_head *bh, | 2947 | static int ocfs2_merge_rec_left(struct inode *inode, |
2948 | struct ocfs2_path *right_path, | ||
2763 | handle_t *handle, | 2949 | handle_t *handle, |
2764 | struct ocfs2_extent_rec *split_rec, | 2950 | struct ocfs2_extent_rec *split_rec, |
2765 | struct ocfs2_extent_list *el, int index) | 2951 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
2952 | int index) | ||
2766 | { | 2953 | { |
2767 | int ret, has_empty_extent = 0; | 2954 | int ret, i, subtree_index = 0, has_empty_extent = 0; |
2768 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); | 2955 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); |
2769 | struct ocfs2_extent_rec *left_rec; | 2956 | struct ocfs2_extent_rec *left_rec; |
2770 | struct ocfs2_extent_rec *right_rec; | 2957 | struct ocfs2_extent_rec *right_rec; |
2958 | struct ocfs2_extent_list *el = path_leaf_el(right_path); | ||
2959 | struct buffer_head *bh = path_leaf_bh(right_path); | ||
2960 | struct buffer_head *root_bh = NULL; | ||
2961 | struct ocfs2_path *left_path = NULL; | ||
2962 | struct ocfs2_extent_list *left_el; | ||
2771 | 2963 | ||
2772 | BUG_ON(index <= 0); | 2964 | BUG_ON(index < 0); |
2773 | 2965 | ||
2774 | left_rec = &el->l_recs[index - 1]; | ||
2775 | right_rec = &el->l_recs[index]; | 2966 | right_rec = &el->l_recs[index]; |
2776 | if (ocfs2_is_empty_extent(&el->l_recs[0])) | 2967 | if (index == 0) { |
2777 | has_empty_extent = 1; | 2968 | /* we meet with a cross extent block merge. */ |
2969 | ret = ocfs2_get_left_path(inode, right_path, &left_path); | ||
2970 | if (ret) { | ||
2971 | mlog_errno(ret); | ||
2972 | goto out; | ||
2973 | } | ||
2974 | |||
2975 | left_el = path_leaf_el(left_path); | ||
2976 | BUG_ON(le16_to_cpu(left_el->l_next_free_rec) != | ||
2977 | le16_to_cpu(left_el->l_count)); | ||
2978 | |||
2979 | left_rec = &left_el->l_recs[ | ||
2980 | le16_to_cpu(left_el->l_next_free_rec) - 1]; | ||
2981 | BUG_ON(le32_to_cpu(left_rec->e_cpos) + | ||
2982 | le16_to_cpu(left_rec->e_leaf_clusters) != | ||
2983 | le32_to_cpu(split_rec->e_cpos)); | ||
2984 | |||
2985 | subtree_index = ocfs2_find_subtree_root(inode, | ||
2986 | left_path, right_path); | ||
2987 | |||
2988 | ret = ocfs2_extend_rotate_transaction(handle, subtree_index, | ||
2989 | handle->h_buffer_credits, | ||
2990 | left_path); | ||
2991 | if (ret) { | ||
2992 | mlog_errno(ret); | ||
2993 | goto out; | ||
2994 | } | ||
2995 | |||
2996 | root_bh = left_path->p_node[subtree_index].bh; | ||
2997 | BUG_ON(root_bh != right_path->p_node[subtree_index].bh); | ||
2998 | |||
2999 | ret = ocfs2_journal_access(handle, inode, root_bh, | ||
3000 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3001 | if (ret) { | ||
3002 | mlog_errno(ret); | ||
3003 | goto out; | ||
3004 | } | ||
3005 | |||
3006 | for (i = subtree_index + 1; | ||
3007 | i < path_num_items(right_path); i++) { | ||
3008 | ret = ocfs2_journal_access(handle, inode, | ||
3009 | right_path->p_node[i].bh, | ||
3010 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3011 | if (ret) { | ||
3012 | mlog_errno(ret); | ||
3013 | goto out; | ||
3014 | } | ||
3015 | |||
3016 | ret = ocfs2_journal_access(handle, inode, | ||
3017 | left_path->p_node[i].bh, | ||
3018 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3019 | if (ret) { | ||
3020 | mlog_errno(ret); | ||
3021 | goto out; | ||
3022 | } | ||
3023 | } | ||
3024 | } else { | ||
3025 | left_rec = &el->l_recs[index - 1]; | ||
3026 | if (ocfs2_is_empty_extent(&el->l_recs[0])) | ||
3027 | has_empty_extent = 1; | ||
3028 | } | ||
2778 | 3029 | ||
2779 | ret = ocfs2_journal_access(handle, inode, bh, | 3030 | ret = ocfs2_journal_access(handle, inode, bh, |
2780 | OCFS2_JOURNAL_ACCESS_WRITE); | 3031 | OCFS2_JOURNAL_ACCESS_WRITE); |
@@ -2790,9 +3041,8 @@ static int ocfs2_merge_rec_left(struct inode *inode, struct buffer_head *bh, | |||
2790 | *left_rec = *split_rec; | 3041 | *left_rec = *split_rec; |
2791 | 3042 | ||
2792 | has_empty_extent = 0; | 3043 | has_empty_extent = 0; |
2793 | } else { | 3044 | } else |
2794 | le16_add_cpu(&left_rec->e_leaf_clusters, split_clusters); | 3045 | le16_add_cpu(&left_rec->e_leaf_clusters, split_clusters); |
2795 | } | ||
2796 | 3046 | ||
2797 | le32_add_cpu(&right_rec->e_cpos, split_clusters); | 3047 | le32_add_cpu(&right_rec->e_cpos, split_clusters); |
2798 | le64_add_cpu(&right_rec->e_blkno, | 3048 | le64_add_cpu(&right_rec->e_blkno, |
@@ -2805,13 +3055,44 @@ static int ocfs2_merge_rec_left(struct inode *inode, struct buffer_head *bh, | |||
2805 | if (ret) | 3055 | if (ret) |
2806 | mlog_errno(ret); | 3056 | mlog_errno(ret); |
2807 | 3057 | ||
3058 | if (left_path) { | ||
3059 | ret = ocfs2_journal_dirty(handle, path_leaf_bh(left_path)); | ||
3060 | if (ret) | ||
3061 | mlog_errno(ret); | ||
3062 | |||
3063 | /* | ||
3064 | * In the situation that the right_rec is empty and the extent | ||
3065 | * block is empty also, ocfs2_complete_edge_insert can't handle | ||
3066 | * it and we need to delete the right extent block. | ||
3067 | */ | ||
3068 | if (le16_to_cpu(right_rec->e_leaf_clusters) == 0 && | ||
3069 | le16_to_cpu(el->l_next_free_rec) == 1) { | ||
3070 | |||
3071 | ret = ocfs2_remove_rightmost_path(inode, handle, | ||
3072 | right_path, dealloc); | ||
3073 | if (ret) { | ||
3074 | mlog_errno(ret); | ||
3075 | goto out; | ||
3076 | } | ||
3077 | |||
3078 | /* Now the rightmost extent block has been deleted. | ||
3079 | * So we use the new rightmost path. | ||
3080 | */ | ||
3081 | ocfs2_mv_path(right_path, left_path); | ||
3082 | left_path = NULL; | ||
3083 | } else | ||
3084 | ocfs2_complete_edge_insert(inode, handle, left_path, | ||
3085 | right_path, subtree_index); | ||
3086 | } | ||
2808 | out: | 3087 | out: |
3088 | if (left_path) | ||
3089 | ocfs2_free_path(left_path); | ||
2809 | return ret; | 3090 | return ret; |
2810 | } | 3091 | } |
2811 | 3092 | ||
2812 | static int ocfs2_try_to_merge_extent(struct inode *inode, | 3093 | static int ocfs2_try_to_merge_extent(struct inode *inode, |
2813 | handle_t *handle, | 3094 | handle_t *handle, |
2814 | struct ocfs2_path *left_path, | 3095 | struct ocfs2_path *path, |
2815 | int split_index, | 3096 | int split_index, |
2816 | struct ocfs2_extent_rec *split_rec, | 3097 | struct ocfs2_extent_rec *split_rec, |
2817 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 3098 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
@@ -2819,7 +3100,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2819 | 3100 | ||
2820 | { | 3101 | { |
2821 | int ret = 0; | 3102 | int ret = 0; |
2822 | struct ocfs2_extent_list *el = path_leaf_el(left_path); | 3103 | struct ocfs2_extent_list *el = path_leaf_el(path); |
2823 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; | 3104 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; |
2824 | 3105 | ||
2825 | BUG_ON(ctxt->c_contig_type == CONTIG_NONE); | 3106 | BUG_ON(ctxt->c_contig_type == CONTIG_NONE); |
@@ -2832,7 +3113,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2832 | * extents - having more than one in a leaf is | 3113 | * extents - having more than one in a leaf is |
2833 | * illegal. | 3114 | * illegal. |
2834 | */ | 3115 | */ |
2835 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | 3116 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
2836 | dealloc); | 3117 | dealloc); |
2837 | if (ret) { | 3118 | if (ret) { |
2838 | mlog_errno(ret); | 3119 | mlog_errno(ret); |
@@ -2847,7 +3128,6 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2847 | * Left-right contig implies this. | 3128 | * Left-right contig implies this. |
2848 | */ | 3129 | */ |
2849 | BUG_ON(!ctxt->c_split_covers_rec); | 3130 | BUG_ON(!ctxt->c_split_covers_rec); |
2850 | BUG_ON(split_index == 0); | ||
2851 | 3131 | ||
2852 | /* | 3132 | /* |
2853 | * Since the leftright insert always covers the entire | 3133 | * Since the leftright insert always covers the entire |
@@ -2858,9 +3138,14 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2858 | * Since the adding of an empty extent shifts | 3138 | * Since the adding of an empty extent shifts |
2859 | * everything back to the right, there's no need to | 3139 | * everything back to the right, there's no need to |
2860 | * update split_index here. | 3140 | * update split_index here. |
3141 | * | ||
3142 | * When the split_index is zero, we need to merge it to the | ||
3143 | * prevoius extent block. It is more efficient and easier | ||
3144 | * if we do merge_right first and merge_left later. | ||
2861 | */ | 3145 | */ |
2862 | ret = ocfs2_merge_rec_left(inode, path_leaf_bh(left_path), | 3146 | ret = ocfs2_merge_rec_right(inode, path, |
2863 | handle, split_rec, el, split_index); | 3147 | handle, split_rec, |
3148 | split_index); | ||
2864 | if (ret) { | 3149 | if (ret) { |
2865 | mlog_errno(ret); | 3150 | mlog_errno(ret); |
2866 | goto out; | 3151 | goto out; |
@@ -2871,32 +3156,30 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2871 | */ | 3156 | */ |
2872 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); | 3157 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); |
2873 | 3158 | ||
2874 | /* | 3159 | /* The merge left us with an empty extent, remove it. */ |
2875 | * The left merge left us with an empty extent, remove | 3160 | ret = ocfs2_rotate_tree_left(inode, handle, path, dealloc); |
2876 | * it. | ||
2877 | */ | ||
2878 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, dealloc); | ||
2879 | if (ret) { | 3161 | if (ret) { |
2880 | mlog_errno(ret); | 3162 | mlog_errno(ret); |
2881 | goto out; | 3163 | goto out; |
2882 | } | 3164 | } |
2883 | split_index--; | 3165 | |
2884 | rec = &el->l_recs[split_index]; | 3166 | rec = &el->l_recs[split_index]; |
2885 | 3167 | ||
2886 | /* | 3168 | /* |
2887 | * Note that we don't pass split_rec here on purpose - | 3169 | * Note that we don't pass split_rec here on purpose - |
2888 | * we've merged it into the left side. | 3170 | * we've merged it into the rec already. |
2889 | */ | 3171 | */ |
2890 | ret = ocfs2_merge_rec_right(inode, path_leaf_bh(left_path), | 3172 | ret = ocfs2_merge_rec_left(inode, path, |
2891 | handle, rec, el, split_index); | 3173 | handle, rec, |
3174 | dealloc, | ||
3175 | split_index); | ||
3176 | |||
2892 | if (ret) { | 3177 | if (ret) { |
2893 | mlog_errno(ret); | 3178 | mlog_errno(ret); |
2894 | goto out; | 3179 | goto out; |
2895 | } | 3180 | } |
2896 | 3181 | ||
2897 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); | 3182 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
2898 | |||
2899 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | ||
2900 | dealloc); | 3183 | dealloc); |
2901 | /* | 3184 | /* |
2902 | * Error from this last rotate is not critical, so | 3185 | * Error from this last rotate is not critical, so |
@@ -2915,8 +3198,9 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2915 | */ | 3198 | */ |
2916 | if (ctxt->c_contig_type == CONTIG_RIGHT) { | 3199 | if (ctxt->c_contig_type == CONTIG_RIGHT) { |
2917 | ret = ocfs2_merge_rec_left(inode, | 3200 | ret = ocfs2_merge_rec_left(inode, |
2918 | path_leaf_bh(left_path), | 3201 | path, |
2919 | handle, split_rec, el, | 3202 | handle, split_rec, |
3203 | dealloc, | ||
2920 | split_index); | 3204 | split_index); |
2921 | if (ret) { | 3205 | if (ret) { |
2922 | mlog_errno(ret); | 3206 | mlog_errno(ret); |
@@ -2924,8 +3208,8 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2924 | } | 3208 | } |
2925 | } else { | 3209 | } else { |
2926 | ret = ocfs2_merge_rec_right(inode, | 3210 | ret = ocfs2_merge_rec_right(inode, |
2927 | path_leaf_bh(left_path), | 3211 | path, |
2928 | handle, split_rec, el, | 3212 | handle, split_rec, |
2929 | split_index); | 3213 | split_index); |
2930 | if (ret) { | 3214 | if (ret) { |
2931 | mlog_errno(ret); | 3215 | mlog_errno(ret); |
@@ -2938,7 +3222,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2938 | * The merge may have left an empty extent in | 3222 | * The merge may have left an empty extent in |
2939 | * our leaf. Try to rotate it away. | 3223 | * our leaf. Try to rotate it away. |
2940 | */ | 3224 | */ |
2941 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | 3225 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
2942 | dealloc); | 3226 | dealloc); |
2943 | if (ret) | 3227 | if (ret) |
2944 | mlog_errno(ret); | 3228 | mlog_errno(ret); |