extents.c (47ea3bb59cf47298b1cbb4d7bef056b3afea0879) | extents.c (667eff35a1f56fa74ce98a0c7c29a40adc1ba4e3) |
---|---|
1/* 2 * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com 3 * Written by Alex Tomas <alex@clusterfs.com> 4 * 5 * Architecture independence: 6 * Copyright (c) 2005, Bull S.A. 7 * Written by Pierre Peiffer <pierre.peiffer@bull.net> 8 * --- 2743 unchanged lines hidden (view full) --- 2752 * b> Splits in two extents: Write is happening at either end of the extent 2753 * c> Splits in three extents: Somone is writing in middle of the extent 2754 */ 2755static int ext4_ext_convert_to_initialized(handle_t *handle, 2756 struct inode *inode, 2757 struct ext4_map_blocks *map, 2758 struct ext4_ext_path *path) 2759{ | 1/* 2 * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com 3 * Written by Alex Tomas <alex@clusterfs.com> 4 * 5 * Architecture independence: 6 * Copyright (c) 2005, Bull S.A. 7 * Written by Pierre Peiffer <pierre.peiffer@bull.net> 8 * --- 2743 unchanged lines hidden (view full) --- 2752 * b> Splits in two extents: Write is happening at either end of the extent 2753 * c> Splits in three extents: Somone is writing in middle of the extent 2754 */ 2755static int ext4_ext_convert_to_initialized(handle_t *handle, 2756 struct inode *inode, 2757 struct ext4_map_blocks *map, 2758 struct ext4_ext_path *path) 2759{ |
2760 struct ext4_extent *ex, newex, orig_ex; 2761 struct ext4_extent *ex1 = NULL; 2762 struct ext4_extent *ex2 = NULL; 2763 struct ext4_extent *ex3 = NULL; 2764 struct ext4_extent_header *eh; | 2760 struct ext4_map_blocks split_map; 2761 struct ext4_extent zero_ex; 2762 struct ext4_extent *ex; |
2765 ext4_lblk_t ee_block, eof_block; 2766 unsigned int allocated, ee_len, depth; | 2763 ext4_lblk_t ee_block, eof_block; 2764 unsigned int allocated, ee_len, depth; |
2767 ext4_fsblk_t newblock; | |
2768 int err = 0; | 2765 int err = 0; |
2769 int ret = 0; 2770 int may_zeroout; | 2766 int split_flag = 0; |
2771 2772 ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical" 2773 "block %llu, max_blocks %u\n", inode->i_ino, 2774 (unsigned long long)map->m_lblk, map->m_len); 2775 2776 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> 2777 inode->i_sb->s_blocksize_bits; 2778 if (eof_block < map->m_lblk + map->m_len) 2779 eof_block = map->m_lblk + map->m_len; 2780 2781 depth = ext_depth(inode); | 2767 2768 ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical" 2769 "block %llu, max_blocks %u\n", inode->i_ino, 2770 (unsigned long long)map->m_lblk, map->m_len); 2771 2772 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> 2773 inode->i_sb->s_blocksize_bits; 2774 if (eof_block < map->m_lblk + map->m_len) 2775 eof_block = map->m_lblk + map->m_len; 2776 2777 depth = ext_depth(inode); |
2782 eh = path[depth].p_hdr; | |
2783 ex = path[depth].p_ext; 2784 ee_block = le32_to_cpu(ex->ee_block); 2785 ee_len = ext4_ext_get_actual_len(ex); 2786 allocated = ee_len - (map->m_lblk - ee_block); | 2778 ex = path[depth].p_ext; 2779 ee_block = le32_to_cpu(ex->ee_block); 2780 ee_len = ext4_ext_get_actual_len(ex); 2781 allocated = ee_len - (map->m_lblk - ee_block); |
2787 newblock = map->m_lblk - ee_block + ext4_ext_pblock(ex); | |
2788 | 2782 |
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 | 2783 WARN_ON(map->m_lblk < ee_block); |
2794 /* 2795 * It is safe to convert extent to initialized via explicit 2796 * zeroout only if extent is fully insde i_size or new_size. 2797 */ | 2784 /* 2785 * It is safe to convert extent to initialized via explicit 2786 * zeroout only if extent is fully insde i_size or new_size. 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) { 2805 err = ext4_ext_zeroout(inode, &orig_ex); | 2791 if (ee_len <= 2*EXT4_EXT_ZERO_LEN && 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 2952 err = ext4_ext_get_access(handle, inode, path + depth); 2953 if (err) 2954 goto out; | 2796 2797 err = ext4_ext_get_access(handle, inode, path + depth); 2798 if (err) 2799 goto out; |
2955 2956 allocated = map->m_len; 2957 2958 /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying 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 } | 2800 ext4_ext_mark_initialized(ex); 2801 ext4_ext_try_to_merge(inode, path, ex); 2802 err = ext4_ext_dirty(handle, inode, path + depth); 2803 goto out; |
2976 } | 2804 } |
2805 |
|
2977 /* | 2806 /* |
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 | 2807 * four cases: 2808 * 1. split the extent into three extents. 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. |
2981 */ | 2812 */ |
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); | 2813 split_map.m_lblk = map->m_lblk; 2814 split_map.m_len = map->m_len; 2815 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); |
3008 if (err) 3009 goto out; | 2826 if (err) 2827 goto out; |
3010 depth = ext_depth(inode); 3011 ex2--; | 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; |
3012 } 3013 } | 2849 } 2850 } |
3014 /* 3015 * Try to Merge towards right. This might be required 3016 * only when the whole extent is being written to. 3017 * i.e. ex2 == ex and ex3 == NULL. 3018 */ 3019 if (!ex3) { 3020 ret = ext4_ext_try_to_merge(inode, path, ex2); 3021 if (ret) { 3022 err = ext4_ext_correct_indexes(handle, inode, path); 3023 if (err) 3024 goto out; 3025 } 3026 } 3027 /* Mark modified extent as dirty */ 3028 err = ext4_ext_dirty(handle, inode, path + depth); 3029 goto out; 3030insert: 3031 err = ext4_ext_insert_extent(handle, inode, path, &newex, 0); 3032 if (err == -ENOSPC && may_zeroout) { 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; | 2851 2852 allocated = ext4_split_extent(handle, inode, path, 2853 &split_map, split_flag, 0); 2854 if (allocated < 0) 2855 err = allocated; 2856 |
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} 3057 3058/* 3059 * This function is called by ext4_ext_map_blocks() from 3060 * ext4_get_blocks_dio_write() when DIO to write 3061 * to an uninitialized extent. 3062 * 3063 * Writing to an uninitialized extent may result in splitting the uninitialized --- 14 unchanged lines hidden (view full) --- 3078 * Returns the size of uninitialized extent to be written on success. 3079 */ 3080static int ext4_split_unwritten_extents(handle_t *handle, 3081 struct inode *inode, 3082 struct ext4_map_blocks *map, 3083 struct ext4_ext_path *path, 3084 int flags) 3085{ | 2859} 2860 2861/* 2862 * This function is called by ext4_ext_map_blocks() from 2863 * ext4_get_blocks_dio_write() when DIO to write 2864 * to an uninitialized extent. 2865 * 2866 * Writing to an uninitialized extent may result in splitting the uninitialized --- 14 unchanged lines hidden (view full) --- 2881 * Returns the size of uninitialized extent to be written on success. 2882 */ 2883static int ext4_split_unwritten_extents(handle_t *handle, 2884 struct inode *inode, 2885 struct ext4_map_blocks *map, 2886 struct ext4_ext_path *path, 2887 int flags) 2888{ |
3086 struct ext4_extent *ex, newex, orig_ex; 3087 struct ext4_extent *ex1 = NULL; 3088 struct ext4_extent *ex2 = NULL; 3089 struct ext4_extent *ex3 = NULL; 3090 ext4_lblk_t ee_block, eof_block; 3091 unsigned int allocated, ee_len, depth; 3092 ext4_fsblk_t newblock; 3093 int err = 0; 3094 int may_zeroout; | 2889 ext4_lblk_t eof_block; 2890 ext4_lblk_t ee_block; 2891 struct ext4_extent *ex; 2892 unsigned int ee_len; 2893 int split_flag = 0, depth; |
3095 3096 ext_debug("ext4_split_unwritten_extents: inode %lu, logical" 3097 "block %llu, max_blocks %u\n", inode->i_ino, 3098 (unsigned long long)map->m_lblk, map->m_len); 3099 3100 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> 3101 inode->i_sb->s_blocksize_bits; 3102 if (eof_block < map->m_lblk + map->m_len) 3103 eof_block = map->m_lblk + map->m_len; | 2894 2895 ext_debug("ext4_split_unwritten_extents: inode %lu, logical" 2896 "block %llu, max_blocks %u\n", inode->i_ino, 2897 (unsigned long long)map->m_lblk, map->m_len); 2898 2899 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> 2900 inode->i_sb->s_blocksize_bits; 2901 if (eof_block < map->m_lblk + map->m_len) 2902 eof_block = map->m_lblk + map->m_len; |
3104 | 2903 /* 2904 * It is safe to convert extent to initialized via explicit 2905 * zeroout only if extent is fully insde i_size or new_size. 2906 */ |
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); | 2907 depth = ext_depth(inode); 2908 ex = path[depth].p_ext; 2909 ee_block = le32_to_cpu(ex->ee_block); 2910 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 | 2911 |
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)); | 2912 split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0; 2913 split_flag |= EXT4_EXT_MARK_UNINIT2; |
3116 | 2914 |
3117 /* 3118 * It is safe to convert extent to initialized via explicit 3119 * zeroout only if extent is fully insde i_size or new_size. 3120 */ 3121 may_zeroout = ee_block + ee_len <= eof_block; 3122 3123 /* 3124 * If the uninitialized extent begins at the same logical 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 3196 err = ext4_ext_get_access(handle, inode, path + depth); 3197 if (err) 3198 goto out; 3199 3200 allocated = map->m_len; 3201 } 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; | 2915 flags |= EXT4_GET_BLOCKS_PRE_IO; 2916 return ext4_split_extent(handle, inode, path, map, split_flag, flags); |
3253} 3254 3255static int ext4_convert_unwritten_extents_endio(handle_t *handle, 3256 struct inode *inode, 3257 struct ext4_ext_path *path) 3258{ 3259 struct ext4_extent *ex; 3260 struct ext4_extent_header *eh; --- 979 unchanged lines hidden --- | 2917} 2918 2919static int ext4_convert_unwritten_extents_endio(handle_t *handle, 2920 struct inode *inode, 2921 struct ext4_ext_path *path) 2922{ 2923 struct ext4_extent *ex; 2924 struct ext4_extent_header *eh; --- 979 unchanged lines hidden --- |