aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorYongqiang Yang <xiaoqiangnk@gmail.com>2011-05-03 12:25:07 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-03 12:25:07 -0400
commit667eff35a1f56fa74ce98a0c7c29a40adc1ba4e3 (patch)
tree625caf470f97ebd544cc19a06dc2921b34708aa8 /fs/ext4
parent47ea3bb59cf47298b1cbb4d7bef056b3afea0879 (diff)
ext4: reimplement convert and split_unwritten
Reimplement ext4_ext_convert_to_initialized() and ext4_split_unwritten_extents() using ext4_split_extent() Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Tested-by: Allison Henderson <achender@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/extents.c480
1 files changed, 72 insertions, 408 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 10317eb1d2a..e363f21b091 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2757,17 +2757,13 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2757 struct ext4_map_blocks *map, 2757 struct ext4_map_blocks *map,
2758 struct ext4_ext_path *path) 2758 struct ext4_ext_path *path)
2759{ 2759{
2760 struct ext4_extent *ex, newex, orig_ex; 2760 struct ext4_map_blocks split_map;
2761 struct ext4_extent *ex1 = NULL; 2761 struct ext4_extent zero_ex;
2762 struct ext4_extent *ex2 = NULL; 2762 struct ext4_extent *ex;
2763 struct ext4_extent *ex3 = NULL;
2764 struct ext4_extent_header *eh;
2765 ext4_lblk_t ee_block, eof_block; 2763 ext4_lblk_t ee_block, eof_block;
2766 unsigned int allocated, ee_len, depth; 2764 unsigned int allocated, ee_len, depth;
2767 ext4_fsblk_t newblock;
2768 int err = 0; 2765 int err = 0;
2769 int ret = 0; 2766 int split_flag = 0;
2770 int may_zeroout;
2771 2767
2772 ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical" 2768 ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical"
2773 "block %llu, max_blocks %u\n", inode->i_ino, 2769 "block %llu, max_blocks %u\n", inode->i_ino,
@@ -2779,280 +2775,87 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2779 eof_block = map->m_lblk + map->m_len; 2775 eof_block = map->m_lblk + map->m_len;
2780 2776
2781 depth = ext_depth(inode); 2777 depth = ext_depth(inode);
2782 eh = path[depth].p_hdr;
2783 ex = path[depth].p_ext; 2778 ex = path[depth].p_ext;
2784 ee_block = le32_to_cpu(ex->ee_block); 2779 ee_block = le32_to_cpu(ex->ee_block);
2785 ee_len = ext4_ext_get_actual_len(ex); 2780 ee_len = ext4_ext_get_actual_len(ex);
2786 allocated = ee_len - (map->m_lblk - ee_block); 2781 allocated = ee_len - (map->m_lblk - ee_block);
2787 newblock = map->m_lblk - ee_block + ext4_ext_pblock(ex);
2788
2789 ex2 = ex;
2790 orig_ex.ee_block = ex->ee_block;
2791 orig_ex.ee_len = cpu_to_le16(ee_len);
2792 ext4_ext_store_pblock(&orig_ex, ext4_ext_pblock(ex));
2793 2782
2783 WARN_ON(map->m_lblk < ee_block);
2794 /* 2784 /*
2795 * It is safe to convert extent to initialized via explicit 2785 * It is safe to convert extent to initialized via explicit
2796 * zeroout only if extent is fully insde i_size or new_size. 2786 * zeroout only if extent is fully insde i_size or new_size.
2797 */ 2787 */
2798 may_zeroout = ee_block + ee_len <= eof_block; 2788 split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
2799 2789
2800 err = ext4_ext_get_access(handle, inode, path + depth);
2801 if (err)
2802 goto out;
2803 /* If extent has less than 2*EXT4_EXT_ZERO_LEN zerout directly */ 2790 /* If extent has less than 2*EXT4_EXT_ZERO_LEN zerout directly */
2804 if (ee_len <= 2*EXT4_EXT_ZERO_LEN && may_zeroout) { 2791 if (ee_len <= 2*EXT4_EXT_ZERO_LEN &&
2805 err = ext4_ext_zeroout(inode, &orig_ex); 2792 (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
2793 err = ext4_ext_zeroout(inode, ex);
2806 if (err) 2794 if (err)
2807 goto fix_extent_len;
2808 /* update the extent length and mark as initialized */
2809 ex->ee_block = orig_ex.ee_block;
2810 ex->ee_len = orig_ex.ee_len;
2811 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
2812 ext4_ext_dirty(handle, inode, path + depth);
2813 /* zeroed the full extent */
2814 return allocated;
2815 }
2816
2817 /* ex1: ee_block to map->m_lblk - 1 : uninitialized */
2818 if (map->m_lblk > ee_block) {
2819 ex1 = ex;
2820 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
2821 ext4_ext_mark_uninitialized(ex1);
2822 ex2 = &newex;
2823 }
2824 /*
2825 * for sanity, update the length of the ex2 extent before
2826 * we insert ex3, if ex1 is NULL. This is to avoid temporary
2827 * overlap of blocks.
2828 */
2829 if (!ex1 && allocated > map->m_len)
2830 ex2->ee_len = cpu_to_le16(map->m_len);
2831 /* ex3: to ee_block + ee_len : uninitialised */
2832 if (allocated > map->m_len) {
2833 unsigned int newdepth;
2834 /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */
2835 if (allocated <= EXT4_EXT_ZERO_LEN && may_zeroout) {
2836 /*
2837 * map->m_lblk == ee_block is handled by the zerouout
2838 * at the beginning.
2839 * Mark first half uninitialized.
2840 * Mark second half initialized and zero out the
2841 * initialized extent
2842 */
2843 ex->ee_block = orig_ex.ee_block;
2844 ex->ee_len = cpu_to_le16(ee_len - allocated);
2845 ext4_ext_mark_uninitialized(ex);
2846 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
2847 ext4_ext_dirty(handle, inode, path + depth);
2848
2849 ex3 = &newex;
2850 ex3->ee_block = cpu_to_le32(map->m_lblk);
2851 ext4_ext_store_pblock(ex3, newblock);
2852 ex3->ee_len = cpu_to_le16(allocated);
2853 err = ext4_ext_insert_extent(handle, inode, path,
2854 ex3, 0);
2855 if (err == -ENOSPC) {
2856 err = ext4_ext_zeroout(inode, &orig_ex);
2857 if (err)
2858 goto fix_extent_len;
2859 ex->ee_block = orig_ex.ee_block;
2860 ex->ee_len = orig_ex.ee_len;
2861 ext4_ext_store_pblock(ex,
2862 ext4_ext_pblock(&orig_ex));
2863 ext4_ext_dirty(handle, inode, path + depth);
2864 /* blocks available from map->m_lblk */
2865 return allocated;
2866
2867 } else if (err)
2868 goto fix_extent_len;
2869
2870 /*
2871 * We need to zero out the second half because
2872 * an fallocate request can update file size and
2873 * converting the second half to initialized extent
2874 * implies that we can leak some junk data to user
2875 * space.
2876 */
2877 err = ext4_ext_zeroout(inode, ex3);
2878 if (err) {
2879 /*
2880 * We should actually mark the
2881 * second half as uninit and return error
2882 * Insert would have changed the extent
2883 */
2884 depth = ext_depth(inode);
2885 ext4_ext_drop_refs(path);
2886 path = ext4_ext_find_extent(inode, map->m_lblk,
2887 path);
2888 if (IS_ERR(path)) {
2889 err = PTR_ERR(path);
2890 return err;
2891 }
2892 /* get the second half extent details */
2893 ex = path[depth].p_ext;
2894 err = ext4_ext_get_access(handle, inode,
2895 path + depth);
2896 if (err)
2897 return err;
2898 ext4_ext_mark_uninitialized(ex);
2899 ext4_ext_dirty(handle, inode, path + depth);
2900 return err;
2901 }
2902
2903 /* zeroed the second half */
2904 return allocated;
2905 }
2906 ex3 = &newex;
2907 ex3->ee_block = cpu_to_le32(map->m_lblk + map->m_len);
2908 ext4_ext_store_pblock(ex3, newblock + map->m_len);
2909 ex3->ee_len = cpu_to_le16(allocated - map->m_len);
2910 ext4_ext_mark_uninitialized(ex3);
2911 err = ext4_ext_insert_extent(handle, inode, path, ex3, 0);
2912 if (err == -ENOSPC && may_zeroout) {
2913 err = ext4_ext_zeroout(inode, &orig_ex);
2914 if (err)
2915 goto fix_extent_len;
2916 /* update the extent length and mark as initialized */
2917 ex->ee_block = orig_ex.ee_block;
2918 ex->ee_len = orig_ex.ee_len;
2919 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
2920 ext4_ext_dirty(handle, inode, path + depth);
2921 /* zeroed the full extent */
2922 /* blocks available from map->m_lblk */
2923 return allocated;
2924
2925 } else if (err)
2926 goto fix_extent_len;
2927 /*
2928 * The depth, and hence eh & ex might change
2929 * as part of the insert above.
2930 */
2931 newdepth = ext_depth(inode);
2932 /*
2933 * update the extent length after successful insert of the
2934 * split extent
2935 */
2936 ee_len -= ext4_ext_get_actual_len(ex3);
2937 orig_ex.ee_len = cpu_to_le16(ee_len);
2938 may_zeroout = ee_block + ee_len <= eof_block;
2939
2940 depth = newdepth;
2941 ext4_ext_drop_refs(path);
2942 path = ext4_ext_find_extent(inode, map->m_lblk, path);
2943 if (IS_ERR(path)) {
2944 err = PTR_ERR(path);
2945 goto out; 2795 goto out;
2946 }
2947 eh = path[depth].p_hdr;
2948 ex = path[depth].p_ext;
2949 if (ex2 != &newex)
2950 ex2 = ex;
2951 2796
2952 err = ext4_ext_get_access(handle, inode, path + depth); 2797 err = ext4_ext_get_access(handle, inode, path + depth);
2953 if (err) 2798 if (err)
2954 goto out; 2799 goto out;
2955 2800 ext4_ext_mark_initialized(ex);
2956 allocated = map->m_len; 2801 ext4_ext_try_to_merge(inode, path, ex);
2957 2802 err = ext4_ext_dirty(handle, inode, path + depth);
2958 /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying 2803 goto out;
2959 * to insert a extent in the middle zerout directly
2960 * otherwise give the extent a chance to merge to left
2961 */
2962 if (le16_to_cpu(orig_ex.ee_len) <= EXT4_EXT_ZERO_LEN &&
2963 map->m_lblk != ee_block && may_zeroout) {
2964 err = ext4_ext_zeroout(inode, &orig_ex);
2965 if (err)
2966 goto fix_extent_len;
2967 /* update the extent length and mark as initialized */
2968 ex->ee_block = orig_ex.ee_block;
2969 ex->ee_len = orig_ex.ee_len;
2970 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
2971 ext4_ext_dirty(handle, inode, path + depth);
2972 /* zero out the first half */
2973 /* blocks available from map->m_lblk */
2974 return allocated;
2975 }
2976 }
2977 /*
2978 * If there was a change of depth as part of the
2979 * insertion of ex3 above, we need to update the length
2980 * of the ex1 extent again here
2981 */
2982 if (ex1 && ex1 != ex) {
2983 ex1 = ex;
2984 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
2985 ext4_ext_mark_uninitialized(ex1);
2986 ex2 = &newex;
2987 }
2988 /* ex2: map->m_lblk to map->m_lblk + maxblocks-1 : initialised */
2989 ex2->ee_block = cpu_to_le32(map->m_lblk);
2990 ext4_ext_store_pblock(ex2, newblock);
2991 ex2->ee_len = cpu_to_le16(allocated);
2992 if (ex2 != ex)
2993 goto insert;
2994 /*
2995 * New (initialized) extent starts from the first block
2996 * in the current extent. i.e., ex2 == ex
2997 * We have to see if it can be merged with the extent
2998 * on the left.
2999 */
3000 if (ex2 > EXT_FIRST_EXTENT(eh)) {
3001 /*
3002 * To merge left, pass "ex2 - 1" to try_to_merge(),
3003 * since it merges towards right _only_.
3004 */
3005 ret = ext4_ext_try_to_merge(inode, path, ex2 - 1);
3006 if (ret) {
3007 err = ext4_ext_correct_indexes(handle, inode, path);
3008 if (err)
3009 goto out;
3010 depth = ext_depth(inode);
3011 ex2--;
3012 }
3013 } 2804 }
2805
3014 /* 2806 /*
3015 * Try to Merge towards right. This might be required 2807 * four cases:
3016 * only when the whole extent is being written to. 2808 * 1. split the extent into three extents.
3017 * i.e. ex2 == ex and ex3 == NULL. 2809 * 2. split the extent into two extents, zeroout the first half.
2810 * 3. split the extent into two extents, zeroout the second half.
2811 * 4. split the extent into two extents with out zeroout.
3018 */ 2812 */
3019 if (!ex3) { 2813 split_map.m_lblk = map->m_lblk;
3020 ret = ext4_ext_try_to_merge(inode, path, ex2); 2814 split_map.m_len = map->m_len;
3021 if (ret) { 2815
3022 err = ext4_ext_correct_indexes(handle, inode, path); 2816 if (allocated > map->m_len) {
2817 if (allocated <= EXT4_EXT_ZERO_LEN &&
2818 (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
2819 /* case 3 */
2820 zero_ex.ee_block =
2821 cpu_to_le32(map->m_lblk + map->m_len);
2822 zero_ex.ee_len = cpu_to_le16(allocated - map->m_len);
2823 ext4_ext_store_pblock(&zero_ex,
2824 ext4_ext_pblock(ex) + map->m_lblk - ee_block);
2825 err = ext4_ext_zeroout(inode, &zero_ex);
3023 if (err) 2826 if (err)
3024 goto out; 2827 goto out;
2828 split_map.m_lblk = map->m_lblk;
2829 split_map.m_len = allocated;
2830 } else if ((map->m_lblk - ee_block + map->m_len <
2831 EXT4_EXT_ZERO_LEN) &&
2832 (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
2833 /* case 2 */
2834 if (map->m_lblk != ee_block) {
2835 zero_ex.ee_block = ex->ee_block;
2836 zero_ex.ee_len = cpu_to_le16(map->m_lblk -
2837 ee_block);
2838 ext4_ext_store_pblock(&zero_ex,
2839 ext4_ext_pblock(ex));
2840 err = ext4_ext_zeroout(inode, &zero_ex);
2841 if (err)
2842 goto out;
2843 }
2844
2845 allocated = map->m_lblk - ee_block + map->m_len;
2846
2847 split_map.m_lblk = ee_block;
2848 split_map.m_len = allocated;
3025 } 2849 }
3026 } 2850 }
3027 /* Mark modified extent as dirty */ 2851
3028 err = ext4_ext_dirty(handle, inode, path + depth); 2852 allocated = ext4_split_extent(handle, inode, path,
3029 goto out; 2853 &split_map, split_flag, 0);
3030insert: 2854 if (allocated < 0)
3031 err = ext4_ext_insert_extent(handle, inode, path, &newex, 0); 2855 err = allocated;
3032 if (err == -ENOSPC && may_zeroout) { 2856
3033 err = ext4_ext_zeroout(inode, &orig_ex);
3034 if (err)
3035 goto fix_extent_len;
3036 /* update the extent length and mark as initialized */
3037 ex->ee_block = orig_ex.ee_block;
3038 ex->ee_len = orig_ex.ee_len;
3039 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
3040 ext4_ext_dirty(handle, inode, path + depth);
3041 /* zero out the first half */
3042 return allocated;
3043 } else if (err)
3044 goto fix_extent_len;
3045out: 2857out:
3046 ext4_ext_show_leaf(inode, path);
3047 return err ? err : allocated; 2858 return err ? err : allocated;
3048
3049fix_extent_len:
3050 ex->ee_block = orig_ex.ee_block;
3051 ex->ee_len = orig_ex.ee_len;
3052 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
3053 ext4_ext_mark_uninitialized(ex);
3054 ext4_ext_dirty(handle, inode, path + depth);
3055 return err;
3056} 2859}
3057 2860
3058/* 2861/*
@@ -3083,15 +2886,11 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3083 struct ext4_ext_path *path, 2886 struct ext4_ext_path *path,
3084 int flags) 2887 int flags)
3085{ 2888{
3086 struct ext4_extent *ex, newex, orig_ex; 2889 ext4_lblk_t eof_block;
3087 struct ext4_extent *ex1 = NULL; 2890 ext4_lblk_t ee_block;
3088 struct ext4_extent *ex2 = NULL; 2891 struct ext4_extent *ex;
3089 struct ext4_extent *ex3 = NULL; 2892 unsigned int ee_len;
3090 ext4_lblk_t ee_block, eof_block; 2893 int split_flag = 0, depth;
3091 unsigned int allocated, ee_len, depth;
3092 ext4_fsblk_t newblock;
3093 int err = 0;
3094 int may_zeroout;
3095 2894
3096 ext_debug("ext4_split_unwritten_extents: inode %lu, logical" 2895 ext_debug("ext4_split_unwritten_extents: inode %lu, logical"
3097 "block %llu, max_blocks %u\n", inode->i_ino, 2896 "block %llu, max_blocks %u\n", inode->i_ino,
@@ -3101,155 +2900,20 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3101 inode->i_sb->s_blocksize_bits; 2900 inode->i_sb->s_blocksize_bits;
3102 if (eof_block < map->m_lblk + map->m_len) 2901 if (eof_block < map->m_lblk + map->m_len)
3103 eof_block = map->m_lblk + map->m_len; 2902 eof_block = map->m_lblk + map->m_len;
3104
3105 depth = ext_depth(inode);
3106 ex = path[depth].p_ext;
3107 ee_block = le32_to_cpu(ex->ee_block);
3108 ee_len = ext4_ext_get_actual_len(ex);
3109 allocated = ee_len - (map->m_lblk - ee_block);
3110 newblock = map->m_lblk - ee_block + ext4_ext_pblock(ex);
3111
3112 ex2 = ex;
3113 orig_ex.ee_block = ex->ee_block;
3114 orig_ex.ee_len = cpu_to_le16(ee_len);
3115 ext4_ext_store_pblock(&orig_ex, ext4_ext_pblock(ex));
3116
3117 /* 2903 /*
3118 * It is safe to convert extent to initialized via explicit 2904 * It is safe to convert extent to initialized via explicit
3119 * zeroout only if extent is fully insde i_size or new_size. 2905 * zeroout only if extent is fully insde i_size or new_size.
3120 */ 2906 */
3121 may_zeroout = ee_block + ee_len <= eof_block; 2907 depth = ext_depth(inode);
3122 2908 ex = path[depth].p_ext;
3123 /* 2909 ee_block = le32_to_cpu(ex->ee_block);
3124 * If the uninitialized extent begins at the same logical 2910 ee_len = ext4_ext_get_actual_len(ex);
3125 * block where the write begins, and the write completely
3126 * covers the extent, then we don't need to split it.
3127 */
3128 if ((map->m_lblk == ee_block) && (allocated <= map->m_len))
3129 return allocated;
3130
3131 err = ext4_ext_get_access(handle, inode, path + depth);
3132 if (err)
3133 goto out;
3134 /* ex1: ee_block to map->m_lblk - 1 : uninitialized */
3135 if (map->m_lblk > ee_block) {
3136 ex1 = ex;
3137 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
3138 ext4_ext_mark_uninitialized(ex1);
3139 ex2 = &newex;
3140 }
3141 /*
3142 * for sanity, update the length of the ex2 extent before
3143 * we insert ex3, if ex1 is NULL. This is to avoid temporary
3144 * overlap of blocks.
3145 */
3146 if (!ex1 && allocated > map->m_len)
3147 ex2->ee_len = cpu_to_le16(map->m_len);
3148 /* ex3: to ee_block + ee_len : uninitialised */
3149 if (allocated > map->m_len) {
3150 unsigned int newdepth;
3151 ex3 = &newex;
3152 ex3->ee_block = cpu_to_le32(map->m_lblk + map->m_len);
3153 ext4_ext_store_pblock(ex3, newblock + map->m_len);
3154 ex3->ee_len = cpu_to_le16(allocated - map->m_len);
3155 ext4_ext_mark_uninitialized(ex3);
3156 err = ext4_ext_insert_extent(handle, inode, path, ex3, flags);
3157 if (err == -ENOSPC && may_zeroout) {
3158 err = ext4_ext_zeroout(inode, &orig_ex);
3159 if (err)
3160 goto fix_extent_len;
3161 /* update the extent length and mark as initialized */
3162 ex->ee_block = orig_ex.ee_block;
3163 ex->ee_len = orig_ex.ee_len;
3164 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
3165 ext4_ext_dirty(handle, inode, path + depth);
3166 /* zeroed the full extent */
3167 /* blocks available from map->m_lblk */
3168 return allocated;
3169
3170 } else if (err)
3171 goto fix_extent_len;
3172 /*
3173 * The depth, and hence eh & ex might change
3174 * as part of the insert above.
3175 */
3176 newdepth = ext_depth(inode);
3177 /*
3178 * update the extent length after successful insert of the
3179 * split extent
3180 */
3181 ee_len -= ext4_ext_get_actual_len(ex3);
3182 orig_ex.ee_len = cpu_to_le16(ee_len);
3183 may_zeroout = ee_block + ee_len <= eof_block;
3184
3185 depth = newdepth;
3186 ext4_ext_drop_refs(path);
3187 path = ext4_ext_find_extent(inode, map->m_lblk, path);
3188 if (IS_ERR(path)) {
3189 err = PTR_ERR(path);
3190 goto out;
3191 }
3192 ex = path[depth].p_ext;
3193 if (ex2 != &newex)
3194 ex2 = ex;
3195 2911
3196 err = ext4_ext_get_access(handle, inode, path + depth); 2912 split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
3197 if (err) 2913 split_flag |= EXT4_EXT_MARK_UNINIT2;
3198 goto out;
3199 2914
3200 allocated = map->m_len; 2915 flags |= EXT4_GET_BLOCKS_PRE_IO;
3201 } 2916 return ext4_split_extent(handle, inode, path, map, split_flag, flags);
3202 /*
3203 * If there was a change of depth as part of the
3204 * insertion of ex3 above, we need to update the length
3205 * of the ex1 extent again here
3206 */
3207 if (ex1 && ex1 != ex) {
3208 ex1 = ex;
3209 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
3210 ext4_ext_mark_uninitialized(ex1);
3211 ex2 = &newex;
3212 }
3213 /*
3214 * ex2: map->m_lblk to map->m_lblk + map->m_len-1 : to be written
3215 * using direct I/O, uninitialised still.
3216 */
3217 ex2->ee_block = cpu_to_le32(map->m_lblk);
3218 ext4_ext_store_pblock(ex2, newblock);
3219 ex2->ee_len = cpu_to_le16(allocated);
3220 ext4_ext_mark_uninitialized(ex2);
3221 if (ex2 != ex)
3222 goto insert;
3223 /* Mark modified extent as dirty */
3224 err = ext4_ext_dirty(handle, inode, path + depth);
3225 ext_debug("out here\n");
3226 goto out;
3227insert:
3228 err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
3229 if (err == -ENOSPC && may_zeroout) {
3230 err = ext4_ext_zeroout(inode, &orig_ex);
3231 if (err)
3232 goto fix_extent_len;
3233 /* update the extent length and mark as initialized */
3234 ex->ee_block = orig_ex.ee_block;
3235 ex->ee_len = orig_ex.ee_len;
3236 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
3237 ext4_ext_dirty(handle, inode, path + depth);
3238 /* zero out the first half */
3239 return allocated;
3240 } else if (err)
3241 goto fix_extent_len;
3242out:
3243 ext4_ext_show_leaf(inode, path);
3244 return err ? err : allocated;
3245
3246fix_extent_len:
3247 ex->ee_block = orig_ex.ee_block;
3248 ex->ee_len = orig_ex.ee_len;
3249 ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex));
3250 ext4_ext_mark_uninitialized(ex);
3251 ext4_ext_dirty(handle, inode, path + depth);
3252 return err;
3253} 2917}
3254 2918
3255static int ext4_convert_unwritten_extents_endio(handle_t *handle, 2919static int ext4_convert_unwritten_extents_endio(handle_t *handle,