diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r-- | fs/ocfs2/alloc.c | 465 |
1 files changed, 414 insertions, 51 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 447206eb5c2e..41f84c92094f 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -1029,8 +1029,7 @@ static void ocfs2_rotate_leaf(struct ocfs2_extent_list *el, | |||
1029 | BUG_ON(!next_free); | 1029 | BUG_ON(!next_free); |
1030 | 1030 | ||
1031 | /* The tree code before us didn't allow enough room in the leaf. */ | 1031 | /* The tree code before us didn't allow enough room in the leaf. */ |
1032 | if (el->l_next_free_rec == el->l_count && !has_empty) | 1032 | BUG_ON(el->l_next_free_rec == el->l_count && !has_empty); |
1033 | BUG(); | ||
1034 | 1033 | ||
1035 | /* | 1034 | /* |
1036 | * The easiest way to approach this is to just remove the | 1035 | * The easiest way to approach this is to just remove the |
@@ -1450,6 +1449,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 | 1449 | * - 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 | 1450 | * 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. | 1451 | * can occur at the end of some types of rotation and appending inserts. |
1452 | * - When we've adjusted the last extent record in the left path leaf and the | ||
1453 | * 1st extent record in the right path leaf during cross extent block merge. | ||
1453 | */ | 1454 | */ |
1454 | static void ocfs2_complete_edge_insert(struct inode *inode, handle_t *handle, | 1455 | static void ocfs2_complete_edge_insert(struct inode *inode, handle_t *handle, |
1455 | struct ocfs2_path *left_path, | 1456 | struct ocfs2_path *left_path, |
@@ -2712,24 +2713,147 @@ static void ocfs2_cleanup_merge(struct ocfs2_extent_list *el, | |||
2712 | } | 2713 | } |
2713 | } | 2714 | } |
2714 | 2715 | ||
2716 | static int ocfs2_get_right_path(struct inode *inode, | ||
2717 | struct ocfs2_path *left_path, | ||
2718 | struct ocfs2_path **ret_right_path) | ||
2719 | { | ||
2720 | int ret; | ||
2721 | u32 right_cpos; | ||
2722 | struct ocfs2_path *right_path = NULL; | ||
2723 | struct ocfs2_extent_list *left_el; | ||
2724 | |||
2725 | *ret_right_path = NULL; | ||
2726 | |||
2727 | /* This function shouldn't be called for non-trees. */ | ||
2728 | BUG_ON(left_path->p_tree_depth == 0); | ||
2729 | |||
2730 | left_el = path_leaf_el(left_path); | ||
2731 | BUG_ON(left_el->l_next_free_rec != left_el->l_count); | ||
2732 | |||
2733 | ret = ocfs2_find_cpos_for_right_leaf(inode->i_sb, left_path, | ||
2734 | &right_cpos); | ||
2735 | if (ret) { | ||
2736 | mlog_errno(ret); | ||
2737 | goto out; | ||
2738 | } | ||
2739 | |||
2740 | /* This function shouldn't be called for the rightmost leaf. */ | ||
2741 | BUG_ON(right_cpos == 0); | ||
2742 | |||
2743 | right_path = ocfs2_new_path(path_root_bh(left_path), | ||
2744 | path_root_el(left_path)); | ||
2745 | if (!right_path) { | ||
2746 | ret = -ENOMEM; | ||
2747 | mlog_errno(ret); | ||
2748 | goto out; | ||
2749 | } | ||
2750 | |||
2751 | ret = ocfs2_find_path(inode, right_path, right_cpos); | ||
2752 | if (ret) { | ||
2753 | mlog_errno(ret); | ||
2754 | goto out; | ||
2755 | } | ||
2756 | |||
2757 | *ret_right_path = right_path; | ||
2758 | out: | ||
2759 | if (ret) | ||
2760 | ocfs2_free_path(right_path); | ||
2761 | return ret; | ||
2762 | } | ||
2763 | |||
2715 | /* | 2764 | /* |
2716 | * Remove split_rec clusters from the record at index and merge them | 2765 | * Remove split_rec clusters from the record at index and merge them |
2717 | * onto the beginning of the record at index + 1. | 2766 | * onto the beginning of the record "next" to it. |
2767 | * For index < l_count - 1, the next means the extent rec at index + 1. | ||
2768 | * For index == l_count - 1, the "next" means the 1st extent rec of the | ||
2769 | * next extent block. | ||
2718 | */ | 2770 | */ |
2719 | static int ocfs2_merge_rec_right(struct inode *inode, struct buffer_head *bh, | 2771 | static int ocfs2_merge_rec_right(struct inode *inode, |
2720 | handle_t *handle, | 2772 | struct ocfs2_path *left_path, |
2721 | struct ocfs2_extent_rec *split_rec, | 2773 | handle_t *handle, |
2722 | struct ocfs2_extent_list *el, int index) | 2774 | struct ocfs2_extent_rec *split_rec, |
2775 | int index) | ||
2723 | { | 2776 | { |
2724 | int ret; | 2777 | int ret, next_free, i; |
2725 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); | 2778 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); |
2726 | struct ocfs2_extent_rec *left_rec; | 2779 | struct ocfs2_extent_rec *left_rec; |
2727 | struct ocfs2_extent_rec *right_rec; | 2780 | struct ocfs2_extent_rec *right_rec; |
2781 | struct ocfs2_extent_list *right_el; | ||
2782 | struct ocfs2_path *right_path = NULL; | ||
2783 | int subtree_index = 0; | ||
2784 | struct ocfs2_extent_list *el = path_leaf_el(left_path); | ||
2785 | struct buffer_head *bh = path_leaf_bh(left_path); | ||
2786 | struct buffer_head *root_bh = NULL; | ||
2728 | 2787 | ||
2729 | BUG_ON(index >= le16_to_cpu(el->l_next_free_rec)); | 2788 | BUG_ON(index >= le16_to_cpu(el->l_next_free_rec)); |
2730 | |||
2731 | left_rec = &el->l_recs[index]; | 2789 | left_rec = &el->l_recs[index]; |
2732 | right_rec = &el->l_recs[index + 1]; | 2790 | |
2791 | if (index == le16_to_cpu(el->l_next_free_rec - 1) && | ||
2792 | le16_to_cpu(el->l_next_free_rec) == le16_to_cpu(el->l_count)) { | ||
2793 | /* we meet with a cross extent block merge. */ | ||
2794 | ret = ocfs2_get_right_path(inode, left_path, &right_path); | ||
2795 | if (ret) { | ||
2796 | mlog_errno(ret); | ||
2797 | goto out; | ||
2798 | } | ||
2799 | |||
2800 | right_el = path_leaf_el(right_path); | ||
2801 | next_free = le16_to_cpu(right_el->l_next_free_rec); | ||
2802 | BUG_ON(next_free <= 0); | ||
2803 | right_rec = &right_el->l_recs[0]; | ||
2804 | if (ocfs2_is_empty_extent(right_rec)) { | ||
2805 | BUG_ON(le16_to_cpu(next_free) <= 1); | ||
2806 | right_rec = &right_el->l_recs[1]; | ||
2807 | } | ||
2808 | |||
2809 | BUG_ON(le32_to_cpu(left_rec->e_cpos) + | ||
2810 | le16_to_cpu(left_rec->e_leaf_clusters) != | ||
2811 | le32_to_cpu(right_rec->e_cpos)); | ||
2812 | |||
2813 | subtree_index = ocfs2_find_subtree_root(inode, | ||
2814 | left_path, right_path); | ||
2815 | |||
2816 | ret = ocfs2_extend_rotate_transaction(handle, subtree_index, | ||
2817 | handle->h_buffer_credits, | ||
2818 | right_path); | ||
2819 | if (ret) { | ||
2820 | mlog_errno(ret); | ||
2821 | goto out; | ||
2822 | } | ||
2823 | |||
2824 | root_bh = left_path->p_node[subtree_index].bh; | ||
2825 | BUG_ON(root_bh != right_path->p_node[subtree_index].bh); | ||
2826 | |||
2827 | ret = ocfs2_journal_access(handle, inode, root_bh, | ||
2828 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
2829 | if (ret) { | ||
2830 | mlog_errno(ret); | ||
2831 | goto out; | ||
2832 | } | ||
2833 | |||
2834 | for (i = subtree_index + 1; | ||
2835 | i < path_num_items(right_path); i++) { | ||
2836 | ret = ocfs2_journal_access(handle, inode, | ||
2837 | right_path->p_node[i].bh, | ||
2838 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
2839 | if (ret) { | ||
2840 | mlog_errno(ret); | ||
2841 | goto out; | ||
2842 | } | ||
2843 | |||
2844 | ret = ocfs2_journal_access(handle, inode, | ||
2845 | left_path->p_node[i].bh, | ||
2846 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
2847 | if (ret) { | ||
2848 | mlog_errno(ret); | ||
2849 | goto out; | ||
2850 | } | ||
2851 | } | ||
2852 | |||
2853 | } else { | ||
2854 | BUG_ON(index == le16_to_cpu(el->l_next_free_rec) - 1); | ||
2855 | right_rec = &el->l_recs[index + 1]; | ||
2856 | } | ||
2733 | 2857 | ||
2734 | ret = ocfs2_journal_access(handle, inode, bh, | 2858 | ret = ocfs2_journal_access(handle, inode, bh, |
2735 | OCFS2_JOURNAL_ACCESS_WRITE); | 2859 | OCFS2_JOURNAL_ACCESS_WRITE); |
@@ -2751,30 +2875,156 @@ static int ocfs2_merge_rec_right(struct inode *inode, struct buffer_head *bh, | |||
2751 | if (ret) | 2875 | if (ret) |
2752 | mlog_errno(ret); | 2876 | mlog_errno(ret); |
2753 | 2877 | ||
2878 | if (right_path) { | ||
2879 | ret = ocfs2_journal_dirty(handle, path_leaf_bh(right_path)); | ||
2880 | if (ret) | ||
2881 | mlog_errno(ret); | ||
2882 | |||
2883 | ocfs2_complete_edge_insert(inode, handle, left_path, | ||
2884 | right_path, subtree_index); | ||
2885 | } | ||
2886 | out: | ||
2887 | if (right_path) | ||
2888 | ocfs2_free_path(right_path); | ||
2889 | return ret; | ||
2890 | } | ||
2891 | |||
2892 | static int ocfs2_get_left_path(struct inode *inode, | ||
2893 | struct ocfs2_path *right_path, | ||
2894 | struct ocfs2_path **ret_left_path) | ||
2895 | { | ||
2896 | int ret; | ||
2897 | u32 left_cpos; | ||
2898 | struct ocfs2_path *left_path = NULL; | ||
2899 | |||
2900 | *ret_left_path = NULL; | ||
2901 | |||
2902 | /* This function shouldn't be called for non-trees. */ | ||
2903 | BUG_ON(right_path->p_tree_depth == 0); | ||
2904 | |||
2905 | ret = ocfs2_find_cpos_for_left_leaf(inode->i_sb, | ||
2906 | right_path, &left_cpos); | ||
2907 | if (ret) { | ||
2908 | mlog_errno(ret); | ||
2909 | goto out; | ||
2910 | } | ||
2911 | |||
2912 | /* This function shouldn't be called for the leftmost leaf. */ | ||
2913 | BUG_ON(left_cpos == 0); | ||
2914 | |||
2915 | left_path = ocfs2_new_path(path_root_bh(right_path), | ||
2916 | path_root_el(right_path)); | ||
2917 | if (!left_path) { | ||
2918 | ret = -ENOMEM; | ||
2919 | mlog_errno(ret); | ||
2920 | goto out; | ||
2921 | } | ||
2922 | |||
2923 | ret = ocfs2_find_path(inode, left_path, left_cpos); | ||
2924 | if (ret) { | ||
2925 | mlog_errno(ret); | ||
2926 | goto out; | ||
2927 | } | ||
2928 | |||
2929 | *ret_left_path = left_path; | ||
2754 | out: | 2930 | out: |
2931 | if (ret) | ||
2932 | ocfs2_free_path(left_path); | ||
2755 | return ret; | 2933 | return ret; |
2756 | } | 2934 | } |
2757 | 2935 | ||
2758 | /* | 2936 | /* |
2759 | * Remove split_rec clusters from the record at index and merge them | 2937 | * Remove split_rec clusters from the record at index and merge them |
2760 | * onto the tail of the record at index - 1. | 2938 | * onto the tail of the record "before" it. |
2939 | * For index > 0, the "before" means the extent rec at index - 1. | ||
2940 | * | ||
2941 | * For index == 0, the "before" means the last record of the previous | ||
2942 | * extent block. And there is also a situation that we may need to | ||
2943 | * remove the rightmost leaf extent block in the right_path and change | ||
2944 | * the right path to indicate the new rightmost path. | ||
2761 | */ | 2945 | */ |
2762 | static int ocfs2_merge_rec_left(struct inode *inode, struct buffer_head *bh, | 2946 | static int ocfs2_merge_rec_left(struct inode *inode, |
2947 | struct ocfs2_path *right_path, | ||
2763 | handle_t *handle, | 2948 | handle_t *handle, |
2764 | struct ocfs2_extent_rec *split_rec, | 2949 | struct ocfs2_extent_rec *split_rec, |
2765 | struct ocfs2_extent_list *el, int index) | 2950 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
2951 | int index) | ||
2766 | { | 2952 | { |
2767 | int ret, has_empty_extent = 0; | 2953 | int ret, i, subtree_index = 0, has_empty_extent = 0; |
2768 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); | 2954 | unsigned int split_clusters = le16_to_cpu(split_rec->e_leaf_clusters); |
2769 | struct ocfs2_extent_rec *left_rec; | 2955 | struct ocfs2_extent_rec *left_rec; |
2770 | struct ocfs2_extent_rec *right_rec; | 2956 | struct ocfs2_extent_rec *right_rec; |
2957 | struct ocfs2_extent_list *el = path_leaf_el(right_path); | ||
2958 | struct buffer_head *bh = path_leaf_bh(right_path); | ||
2959 | struct buffer_head *root_bh = NULL; | ||
2960 | struct ocfs2_path *left_path = NULL; | ||
2961 | struct ocfs2_extent_list *left_el; | ||
2771 | 2962 | ||
2772 | BUG_ON(index <= 0); | 2963 | BUG_ON(index < 0); |
2773 | 2964 | ||
2774 | left_rec = &el->l_recs[index - 1]; | ||
2775 | right_rec = &el->l_recs[index]; | 2965 | right_rec = &el->l_recs[index]; |
2776 | if (ocfs2_is_empty_extent(&el->l_recs[0])) | 2966 | if (index == 0) { |
2777 | has_empty_extent = 1; | 2967 | /* we meet with a cross extent block merge. */ |
2968 | ret = ocfs2_get_left_path(inode, right_path, &left_path); | ||
2969 | if (ret) { | ||
2970 | mlog_errno(ret); | ||
2971 | goto out; | ||
2972 | } | ||
2973 | |||
2974 | left_el = path_leaf_el(left_path); | ||
2975 | BUG_ON(le16_to_cpu(left_el->l_next_free_rec) != | ||
2976 | le16_to_cpu(left_el->l_count)); | ||
2977 | |||
2978 | left_rec = &left_el->l_recs[ | ||
2979 | le16_to_cpu(left_el->l_next_free_rec) - 1]; | ||
2980 | BUG_ON(le32_to_cpu(left_rec->e_cpos) + | ||
2981 | le16_to_cpu(left_rec->e_leaf_clusters) != | ||
2982 | le32_to_cpu(split_rec->e_cpos)); | ||
2983 | |||
2984 | subtree_index = ocfs2_find_subtree_root(inode, | ||
2985 | left_path, right_path); | ||
2986 | |||
2987 | ret = ocfs2_extend_rotate_transaction(handle, subtree_index, | ||
2988 | handle->h_buffer_credits, | ||
2989 | left_path); | ||
2990 | if (ret) { | ||
2991 | mlog_errno(ret); | ||
2992 | goto out; | ||
2993 | } | ||
2994 | |||
2995 | root_bh = left_path->p_node[subtree_index].bh; | ||
2996 | BUG_ON(root_bh != right_path->p_node[subtree_index].bh); | ||
2997 | |||
2998 | ret = ocfs2_journal_access(handle, inode, root_bh, | ||
2999 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3000 | if (ret) { | ||
3001 | mlog_errno(ret); | ||
3002 | goto out; | ||
3003 | } | ||
3004 | |||
3005 | for (i = subtree_index + 1; | ||
3006 | i < path_num_items(right_path); i++) { | ||
3007 | ret = ocfs2_journal_access(handle, inode, | ||
3008 | right_path->p_node[i].bh, | ||
3009 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3010 | if (ret) { | ||
3011 | mlog_errno(ret); | ||
3012 | goto out; | ||
3013 | } | ||
3014 | |||
3015 | ret = ocfs2_journal_access(handle, inode, | ||
3016 | left_path->p_node[i].bh, | ||
3017 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3018 | if (ret) { | ||
3019 | mlog_errno(ret); | ||
3020 | goto out; | ||
3021 | } | ||
3022 | } | ||
3023 | } else { | ||
3024 | left_rec = &el->l_recs[index - 1]; | ||
3025 | if (ocfs2_is_empty_extent(&el->l_recs[0])) | ||
3026 | has_empty_extent = 1; | ||
3027 | } | ||
2778 | 3028 | ||
2779 | ret = ocfs2_journal_access(handle, inode, bh, | 3029 | ret = ocfs2_journal_access(handle, inode, bh, |
2780 | OCFS2_JOURNAL_ACCESS_WRITE); | 3030 | OCFS2_JOURNAL_ACCESS_WRITE); |
@@ -2790,9 +3040,8 @@ static int ocfs2_merge_rec_left(struct inode *inode, struct buffer_head *bh, | |||
2790 | *left_rec = *split_rec; | 3040 | *left_rec = *split_rec; |
2791 | 3041 | ||
2792 | has_empty_extent = 0; | 3042 | has_empty_extent = 0; |
2793 | } else { | 3043 | } else |
2794 | le16_add_cpu(&left_rec->e_leaf_clusters, split_clusters); | 3044 | le16_add_cpu(&left_rec->e_leaf_clusters, split_clusters); |
2795 | } | ||
2796 | 3045 | ||
2797 | le32_add_cpu(&right_rec->e_cpos, split_clusters); | 3046 | le32_add_cpu(&right_rec->e_cpos, split_clusters); |
2798 | le64_add_cpu(&right_rec->e_blkno, | 3047 | le64_add_cpu(&right_rec->e_blkno, |
@@ -2805,13 +3054,44 @@ static int ocfs2_merge_rec_left(struct inode *inode, struct buffer_head *bh, | |||
2805 | if (ret) | 3054 | if (ret) |
2806 | mlog_errno(ret); | 3055 | mlog_errno(ret); |
2807 | 3056 | ||
3057 | if (left_path) { | ||
3058 | ret = ocfs2_journal_dirty(handle, path_leaf_bh(left_path)); | ||
3059 | if (ret) | ||
3060 | mlog_errno(ret); | ||
3061 | |||
3062 | /* | ||
3063 | * In the situation that the right_rec is empty and the extent | ||
3064 | * block is empty also, ocfs2_complete_edge_insert can't handle | ||
3065 | * it and we need to delete the right extent block. | ||
3066 | */ | ||
3067 | if (le16_to_cpu(right_rec->e_leaf_clusters) == 0 && | ||
3068 | le16_to_cpu(el->l_next_free_rec) == 1) { | ||
3069 | |||
3070 | ret = ocfs2_remove_rightmost_path(inode, handle, | ||
3071 | right_path, dealloc); | ||
3072 | if (ret) { | ||
3073 | mlog_errno(ret); | ||
3074 | goto out; | ||
3075 | } | ||
3076 | |||
3077 | /* Now the rightmost extent block has been deleted. | ||
3078 | * So we use the new rightmost path. | ||
3079 | */ | ||
3080 | ocfs2_mv_path(right_path, left_path); | ||
3081 | left_path = NULL; | ||
3082 | } else | ||
3083 | ocfs2_complete_edge_insert(inode, handle, left_path, | ||
3084 | right_path, subtree_index); | ||
3085 | } | ||
2808 | out: | 3086 | out: |
3087 | if (left_path) | ||
3088 | ocfs2_free_path(left_path); | ||
2809 | return ret; | 3089 | return ret; |
2810 | } | 3090 | } |
2811 | 3091 | ||
2812 | static int ocfs2_try_to_merge_extent(struct inode *inode, | 3092 | static int ocfs2_try_to_merge_extent(struct inode *inode, |
2813 | handle_t *handle, | 3093 | handle_t *handle, |
2814 | struct ocfs2_path *left_path, | 3094 | struct ocfs2_path *path, |
2815 | int split_index, | 3095 | int split_index, |
2816 | struct ocfs2_extent_rec *split_rec, | 3096 | struct ocfs2_extent_rec *split_rec, |
2817 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 3097 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
@@ -2819,7 +3099,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2819 | 3099 | ||
2820 | { | 3100 | { |
2821 | int ret = 0; | 3101 | int ret = 0; |
2822 | struct ocfs2_extent_list *el = path_leaf_el(left_path); | 3102 | struct ocfs2_extent_list *el = path_leaf_el(path); |
2823 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; | 3103 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; |
2824 | 3104 | ||
2825 | BUG_ON(ctxt->c_contig_type == CONTIG_NONE); | 3105 | BUG_ON(ctxt->c_contig_type == CONTIG_NONE); |
@@ -2832,7 +3112,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2832 | * extents - having more than one in a leaf is | 3112 | * extents - having more than one in a leaf is |
2833 | * illegal. | 3113 | * illegal. |
2834 | */ | 3114 | */ |
2835 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | 3115 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
2836 | dealloc); | 3116 | dealloc); |
2837 | if (ret) { | 3117 | if (ret) { |
2838 | mlog_errno(ret); | 3118 | mlog_errno(ret); |
@@ -2847,7 +3127,6 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2847 | * Left-right contig implies this. | 3127 | * Left-right contig implies this. |
2848 | */ | 3128 | */ |
2849 | BUG_ON(!ctxt->c_split_covers_rec); | 3129 | BUG_ON(!ctxt->c_split_covers_rec); |
2850 | BUG_ON(split_index == 0); | ||
2851 | 3130 | ||
2852 | /* | 3131 | /* |
2853 | * Since the leftright insert always covers the entire | 3132 | * Since the leftright insert always covers the entire |
@@ -2858,9 +3137,14 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2858 | * Since the adding of an empty extent shifts | 3137 | * Since the adding of an empty extent shifts |
2859 | * everything back to the right, there's no need to | 3138 | * everything back to the right, there's no need to |
2860 | * update split_index here. | 3139 | * update split_index here. |
3140 | * | ||
3141 | * When the split_index is zero, we need to merge it to the | ||
3142 | * prevoius extent block. It is more efficient and easier | ||
3143 | * if we do merge_right first and merge_left later. | ||
2861 | */ | 3144 | */ |
2862 | ret = ocfs2_merge_rec_left(inode, path_leaf_bh(left_path), | 3145 | ret = ocfs2_merge_rec_right(inode, path, |
2863 | handle, split_rec, el, split_index); | 3146 | handle, split_rec, |
3147 | split_index); | ||
2864 | if (ret) { | 3148 | if (ret) { |
2865 | mlog_errno(ret); | 3149 | mlog_errno(ret); |
2866 | goto out; | 3150 | goto out; |
@@ -2871,32 +3155,30 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2871 | */ | 3155 | */ |
2872 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); | 3156 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); |
2873 | 3157 | ||
2874 | /* | 3158 | /* The merge left us with an empty extent, remove it. */ |
2875 | * The left merge left us with an empty extent, remove | 3159 | 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) { | 3160 | if (ret) { |
2880 | mlog_errno(ret); | 3161 | mlog_errno(ret); |
2881 | goto out; | 3162 | goto out; |
2882 | } | 3163 | } |
2883 | split_index--; | 3164 | |
2884 | rec = &el->l_recs[split_index]; | 3165 | rec = &el->l_recs[split_index]; |
2885 | 3166 | ||
2886 | /* | 3167 | /* |
2887 | * Note that we don't pass split_rec here on purpose - | 3168 | * Note that we don't pass split_rec here on purpose - |
2888 | * we've merged it into the left side. | 3169 | * we've merged it into the rec already. |
2889 | */ | 3170 | */ |
2890 | ret = ocfs2_merge_rec_right(inode, path_leaf_bh(left_path), | 3171 | ret = ocfs2_merge_rec_left(inode, path, |
2891 | handle, rec, el, split_index); | 3172 | handle, rec, |
3173 | dealloc, | ||
3174 | split_index); | ||
3175 | |||
2892 | if (ret) { | 3176 | if (ret) { |
2893 | mlog_errno(ret); | 3177 | mlog_errno(ret); |
2894 | goto out; | 3178 | goto out; |
2895 | } | 3179 | } |
2896 | 3180 | ||
2897 | BUG_ON(!ocfs2_is_empty_extent(&el->l_recs[0])); | 3181 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
2898 | |||
2899 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | ||
2900 | dealloc); | 3182 | dealloc); |
2901 | /* | 3183 | /* |
2902 | * Error from this last rotate is not critical, so | 3184 | * Error from this last rotate is not critical, so |
@@ -2915,8 +3197,9 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2915 | */ | 3197 | */ |
2916 | if (ctxt->c_contig_type == CONTIG_RIGHT) { | 3198 | if (ctxt->c_contig_type == CONTIG_RIGHT) { |
2917 | ret = ocfs2_merge_rec_left(inode, | 3199 | ret = ocfs2_merge_rec_left(inode, |
2918 | path_leaf_bh(left_path), | 3200 | path, |
2919 | handle, split_rec, el, | 3201 | handle, split_rec, |
3202 | dealloc, | ||
2920 | split_index); | 3203 | split_index); |
2921 | if (ret) { | 3204 | if (ret) { |
2922 | mlog_errno(ret); | 3205 | mlog_errno(ret); |
@@ -2924,8 +3207,8 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2924 | } | 3207 | } |
2925 | } else { | 3208 | } else { |
2926 | ret = ocfs2_merge_rec_right(inode, | 3209 | ret = ocfs2_merge_rec_right(inode, |
2927 | path_leaf_bh(left_path), | 3210 | path, |
2928 | handle, split_rec, el, | 3211 | handle, split_rec, |
2929 | split_index); | 3212 | split_index); |
2930 | if (ret) { | 3213 | if (ret) { |
2931 | mlog_errno(ret); | 3214 | mlog_errno(ret); |
@@ -2938,7 +3221,7 @@ static int ocfs2_try_to_merge_extent(struct inode *inode, | |||
2938 | * The merge may have left an empty extent in | 3221 | * The merge may have left an empty extent in |
2939 | * our leaf. Try to rotate it away. | 3222 | * our leaf. Try to rotate it away. |
2940 | */ | 3223 | */ |
2941 | ret = ocfs2_rotate_tree_left(inode, handle, left_path, | 3224 | ret = ocfs2_rotate_tree_left(inode, handle, path, |
2942 | dealloc); | 3225 | dealloc); |
2943 | if (ret) | 3226 | if (ret) |
2944 | mlog_errno(ret); | 3227 | mlog_errno(ret); |
@@ -3498,20 +3781,57 @@ out: | |||
3498 | } | 3781 | } |
3499 | 3782 | ||
3500 | static enum ocfs2_contig_type | 3783 | static enum ocfs2_contig_type |
3501 | ocfs2_figure_merge_contig_type(struct inode *inode, | 3784 | ocfs2_figure_merge_contig_type(struct inode *inode, struct ocfs2_path *path, |
3502 | struct ocfs2_extent_list *el, int index, | 3785 | struct ocfs2_extent_list *el, int index, |
3503 | struct ocfs2_extent_rec *split_rec) | 3786 | struct ocfs2_extent_rec *split_rec) |
3504 | { | 3787 | { |
3505 | struct ocfs2_extent_rec *rec; | 3788 | int status; |
3506 | enum ocfs2_contig_type ret = CONTIG_NONE; | 3789 | enum ocfs2_contig_type ret = CONTIG_NONE; |
3790 | u32 left_cpos, right_cpos; | ||
3791 | struct ocfs2_extent_rec *rec = NULL; | ||
3792 | struct ocfs2_extent_list *new_el; | ||
3793 | struct ocfs2_path *left_path = NULL, *right_path = NULL; | ||
3794 | struct buffer_head *bh; | ||
3795 | struct ocfs2_extent_block *eb; | ||
3796 | |||
3797 | if (index > 0) { | ||
3798 | rec = &el->l_recs[index - 1]; | ||
3799 | } else if (path->p_tree_depth > 0) { | ||
3800 | status = ocfs2_find_cpos_for_left_leaf(inode->i_sb, | ||
3801 | path, &left_cpos); | ||
3802 | if (status) | ||
3803 | goto out; | ||
3804 | |||
3805 | if (left_cpos != 0) { | ||
3806 | left_path = ocfs2_new_path(path_root_bh(path), | ||
3807 | path_root_el(path)); | ||
3808 | if (!left_path) | ||
3809 | goto out; | ||
3810 | |||
3811 | status = ocfs2_find_path(inode, left_path, left_cpos); | ||
3812 | if (status) | ||
3813 | goto out; | ||
3814 | |||
3815 | new_el = path_leaf_el(left_path); | ||
3816 | |||
3817 | if (le16_to_cpu(new_el->l_next_free_rec) != | ||
3818 | le16_to_cpu(new_el->l_count)) { | ||
3819 | bh = path_leaf_bh(left_path); | ||
3820 | eb = (struct ocfs2_extent_block *)bh->b_data; | ||
3821 | OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, | ||
3822 | eb); | ||
3823 | goto out; | ||
3824 | } | ||
3825 | rec = &new_el->l_recs[ | ||
3826 | le16_to_cpu(new_el->l_next_free_rec) - 1]; | ||
3827 | } | ||
3828 | } | ||
3507 | 3829 | ||
3508 | /* | 3830 | /* |
3509 | * We're careful to check for an empty extent record here - | 3831 | * We're careful to check for an empty extent record here - |
3510 | * the merge code will know what to do if it sees one. | 3832 | * the merge code will know what to do if it sees one. |
3511 | */ | 3833 | */ |
3512 | 3834 | if (rec) { | |
3513 | if (index > 0) { | ||
3514 | rec = &el->l_recs[index - 1]; | ||
3515 | if (index == 1 && ocfs2_is_empty_extent(rec)) { | 3835 | if (index == 1 && ocfs2_is_empty_extent(rec)) { |
3516 | if (split_rec->e_cpos == el->l_recs[index].e_cpos) | 3836 | if (split_rec->e_cpos == el->l_recs[index].e_cpos) |
3517 | ret = CONTIG_RIGHT; | 3837 | ret = CONTIG_RIGHT; |
@@ -3520,10 +3840,45 @@ ocfs2_figure_merge_contig_type(struct inode *inode, | |||
3520 | } | 3840 | } |
3521 | } | 3841 | } |
3522 | 3842 | ||
3523 | if (index < (le16_to_cpu(el->l_next_free_rec) - 1)) { | 3843 | rec = NULL; |
3844 | if (index < (le16_to_cpu(el->l_next_free_rec) - 1)) | ||
3845 | rec = &el->l_recs[index + 1]; | ||
3846 | else if (le16_to_cpu(el->l_next_free_rec) == le16_to_cpu(el->l_count) && | ||
3847 | path->p_tree_depth > 0) { | ||
3848 | status = ocfs2_find_cpos_for_right_leaf(inode->i_sb, | ||
3849 | path, &right_cpos); | ||
3850 | if (status) | ||
3851 | goto out; | ||
3852 | |||
3853 | if (right_cpos == 0) | ||
3854 | goto out; | ||
3855 | |||
3856 | right_path = ocfs2_new_path(path_root_bh(path), | ||
3857 | path_root_el(path)); | ||
3858 | if (!right_path) | ||
3859 | goto out; | ||
3860 | |||
3861 | status = ocfs2_find_path(inode, right_path, right_cpos); | ||
3862 | if (status) | ||
3863 | goto out; | ||
3864 | |||
3865 | new_el = path_leaf_el(right_path); | ||
3866 | rec = &new_el->l_recs[0]; | ||
3867 | if (ocfs2_is_empty_extent(rec)) { | ||
3868 | if (le16_to_cpu(new_el->l_next_free_rec) <= 1) { | ||
3869 | bh = path_leaf_bh(right_path); | ||
3870 | eb = (struct ocfs2_extent_block *)bh->b_data; | ||
3871 | OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, | ||
3872 | eb); | ||
3873 | goto out; | ||
3874 | } | ||
3875 | rec = &new_el->l_recs[1]; | ||
3876 | } | ||
3877 | } | ||
3878 | |||
3879 | if (rec) { | ||
3524 | enum ocfs2_contig_type contig_type; | 3880 | enum ocfs2_contig_type contig_type; |
3525 | 3881 | ||
3526 | rec = &el->l_recs[index + 1]; | ||
3527 | contig_type = ocfs2_extent_contig(inode, rec, split_rec); | 3882 | contig_type = ocfs2_extent_contig(inode, rec, split_rec); |
3528 | 3883 | ||
3529 | if (contig_type == CONTIG_LEFT && ret == CONTIG_RIGHT) | 3884 | if (contig_type == CONTIG_LEFT && ret == CONTIG_RIGHT) |
@@ -3532,6 +3887,12 @@ ocfs2_figure_merge_contig_type(struct inode *inode, | |||
3532 | ret = contig_type; | 3887 | ret = contig_type; |
3533 | } | 3888 | } |
3534 | 3889 | ||
3890 | out: | ||
3891 | if (left_path) | ||
3892 | ocfs2_free_path(left_path); | ||
3893 | if (right_path) | ||
3894 | ocfs2_free_path(right_path); | ||
3895 | |||
3535 | return ret; | 3896 | return ret; |
3536 | } | 3897 | } |
3537 | 3898 | ||
@@ -3994,7 +4355,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
3994 | goto out; | 4355 | goto out; |
3995 | } | 4356 | } |
3996 | 4357 | ||
3997 | ctxt.c_contig_type = ocfs2_figure_merge_contig_type(inode, el, | 4358 | ctxt.c_contig_type = ocfs2_figure_merge_contig_type(inode, path, el, |
3998 | split_index, | 4359 | split_index, |
3999 | split_rec); | 4360 | split_rec); |
4000 | 4361 | ||
@@ -4788,6 +5149,8 @@ static void ocfs2_truncate_log_worker(struct work_struct *work) | |||
4788 | status = ocfs2_flush_truncate_log(osb); | 5149 | status = ocfs2_flush_truncate_log(osb); |
4789 | if (status < 0) | 5150 | if (status < 0) |
4790 | mlog_errno(status); | 5151 | mlog_errno(status); |
5152 | else | ||
5153 | ocfs2_init_inode_steal_slot(osb); | ||
4791 | 5154 | ||
4792 | mlog_exit(status); | 5155 | mlog_exit(status); |
4793 | } | 5156 | } |