diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e3a55eb8b26a..2593f748c3a4 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -326,32 +326,18 @@ ext4_ext_max_entries(struct inode *inode, int depth) | |||
326 | 326 | ||
327 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) | 327 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) |
328 | { | 328 | { |
329 | ext4_fsblk_t block = ext_pblock(ext), valid_block; | 329 | ext4_fsblk_t block = ext_pblock(ext); |
330 | int len = ext4_ext_get_actual_len(ext); | 330 | int len = ext4_ext_get_actual_len(ext); |
331 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | ||
332 | 331 | ||
333 | valid_block = le32_to_cpu(es->s_first_data_block) + | 332 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); |
334 | EXT4_SB(inode->i_sb)->s_gdb_count; | ||
335 | if (unlikely(block <= valid_block || | ||
336 | ((block + len) > ext4_blocks_count(es)))) | ||
337 | return 0; | ||
338 | else | ||
339 | return 1; | ||
340 | } | 333 | } |
341 | 334 | ||
342 | static int ext4_valid_extent_idx(struct inode *inode, | 335 | static int ext4_valid_extent_idx(struct inode *inode, |
343 | struct ext4_extent_idx *ext_idx) | 336 | struct ext4_extent_idx *ext_idx) |
344 | { | 337 | { |
345 | ext4_fsblk_t block = idx_pblock(ext_idx), valid_block; | 338 | ext4_fsblk_t block = idx_pblock(ext_idx); |
346 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | ||
347 | 339 | ||
348 | valid_block = le32_to_cpu(es->s_first_data_block) + | 340 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, 1); |
349 | EXT4_SB(inode->i_sb)->s_gdb_count; | ||
350 | if (unlikely(block <= valid_block || | ||
351 | (block >= ext4_blocks_count(es)))) | ||
352 | return 0; | ||
353 | else | ||
354 | return 1; | ||
355 | } | 341 | } |
356 | 342 | ||
357 | static int ext4_valid_extent_entries(struct inode *inode, | 343 | static int ext4_valid_extent_entries(struct inode *inode, |
@@ -2097,12 +2083,16 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2097 | ex = EXT_LAST_EXTENT(eh); | 2083 | ex = EXT_LAST_EXTENT(eh); |
2098 | 2084 | ||
2099 | ex_ee_block = le32_to_cpu(ex->ee_block); | 2085 | ex_ee_block = le32_to_cpu(ex->ee_block); |
2100 | if (ext4_ext_is_uninitialized(ex)) | ||
2101 | uninitialized = 1; | ||
2102 | ex_ee_len = ext4_ext_get_actual_len(ex); | 2086 | ex_ee_len = ext4_ext_get_actual_len(ex); |
2103 | 2087 | ||
2104 | while (ex >= EXT_FIRST_EXTENT(eh) && | 2088 | while (ex >= EXT_FIRST_EXTENT(eh) && |
2105 | ex_ee_block + ex_ee_len > start) { | 2089 | ex_ee_block + ex_ee_len > start) { |
2090 | |||
2091 | if (ext4_ext_is_uninitialized(ex)) | ||
2092 | uninitialized = 1; | ||
2093 | else | ||
2094 | uninitialized = 0; | ||
2095 | |||
2106 | ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len); | 2096 | ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len); |
2107 | path[depth].p_ext = ex; | 2097 | path[depth].p_ext = ex; |
2108 | 2098 | ||
@@ -2784,7 +2774,7 @@ fix_extent_len: | |||
2784 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2774 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
2785 | ext4_lblk_t iblock, | 2775 | ext4_lblk_t iblock, |
2786 | unsigned int max_blocks, struct buffer_head *bh_result, | 2776 | unsigned int max_blocks, struct buffer_head *bh_result, |
2787 | int create, int extend_disksize) | 2777 | int flags) |
2788 | { | 2778 | { |
2789 | struct ext4_ext_path *path = NULL; | 2779 | struct ext4_ext_path *path = NULL; |
2790 | struct ext4_extent_header *eh; | 2780 | struct ext4_extent_header *eh; |
@@ -2793,7 +2783,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2793 | int err = 0, depth, ret, cache_type; | 2783 | int err = 0, depth, ret, cache_type; |
2794 | unsigned int allocated = 0; | 2784 | unsigned int allocated = 0; |
2795 | struct ext4_allocation_request ar; | 2785 | struct ext4_allocation_request ar; |
2796 | loff_t disksize; | ||
2797 | 2786 | ||
2798 | __clear_bit(BH_New, &bh_result->b_state); | 2787 | __clear_bit(BH_New, &bh_result->b_state); |
2799 | ext_debug("blocks %u/%u requested for inode %u\n", | 2788 | ext_debug("blocks %u/%u requested for inode %u\n", |
@@ -2803,7 +2792,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2803 | cache_type = ext4_ext_in_cache(inode, iblock, &newex); | 2792 | cache_type = ext4_ext_in_cache(inode, iblock, &newex); |
2804 | if (cache_type) { | 2793 | if (cache_type) { |
2805 | if (cache_type == EXT4_EXT_CACHE_GAP) { | 2794 | if (cache_type == EXT4_EXT_CACHE_GAP) { |
2806 | if (!create) { | 2795 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { |
2807 | /* | 2796 | /* |
2808 | * block isn't allocated yet and | 2797 | * block isn't allocated yet and |
2809 | * user doesn't want to allocate it | 2798 | * user doesn't want to allocate it |
@@ -2869,9 +2858,11 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2869 | EXT4_EXT_CACHE_EXTENT); | 2858 | EXT4_EXT_CACHE_EXTENT); |
2870 | goto out; | 2859 | goto out; |
2871 | } | 2860 | } |
2872 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) | 2861 | if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) |
2873 | goto out; | 2862 | goto out; |
2874 | if (!create) { | 2863 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { |
2864 | if (allocated > max_blocks) | ||
2865 | allocated = max_blocks; | ||
2875 | /* | 2866 | /* |
2876 | * We have blocks reserved already. We | 2867 | * We have blocks reserved already. We |
2877 | * return allocated blocks so that delalloc | 2868 | * return allocated blocks so that delalloc |
@@ -2879,8 +2870,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2879 | * the buffer head will be unmapped so that | 2870 | * the buffer head will be unmapped so that |
2880 | * a read from the block returns 0s. | 2871 | * a read from the block returns 0s. |
2881 | */ | 2872 | */ |
2882 | if (allocated > max_blocks) | ||
2883 | allocated = max_blocks; | ||
2884 | set_buffer_unwritten(bh_result); | 2873 | set_buffer_unwritten(bh_result); |
2885 | bh_result->b_bdev = inode->i_sb->s_bdev; | 2874 | bh_result->b_bdev = inode->i_sb->s_bdev; |
2886 | bh_result->b_blocknr = newblock; | 2875 | bh_result->b_blocknr = newblock; |
@@ -2903,7 +2892,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2903 | * requested block isn't allocated yet; | 2892 | * requested block isn't allocated yet; |
2904 | * we couldn't try to create block if create flag is zero | 2893 | * we couldn't try to create block if create flag is zero |
2905 | */ | 2894 | */ |
2906 | if (!create) { | 2895 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { |
2907 | /* | 2896 | /* |
2908 | * put just found gap into cache to speed up | 2897 | * put just found gap into cache to speed up |
2909 | * subsequent requests | 2898 | * subsequent requests |
@@ -2932,10 +2921,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2932 | * EXT_UNINIT_MAX_LEN. | 2921 | * EXT_UNINIT_MAX_LEN. |
2933 | */ | 2922 | */ |
2934 | if (max_blocks > EXT_INIT_MAX_LEN && | 2923 | if (max_blocks > EXT_INIT_MAX_LEN && |
2935 | create != EXT4_CREATE_UNINITIALIZED_EXT) | 2924 | !(flags & EXT4_GET_BLOCKS_UNINIT_EXT)) |
2936 | max_blocks = EXT_INIT_MAX_LEN; | 2925 | max_blocks = EXT_INIT_MAX_LEN; |
2937 | else if (max_blocks > EXT_UNINIT_MAX_LEN && | 2926 | else if (max_blocks > EXT_UNINIT_MAX_LEN && |
2938 | create == EXT4_CREATE_UNINITIALIZED_EXT) | 2927 | (flags & EXT4_GET_BLOCKS_UNINIT_EXT)) |
2939 | max_blocks = EXT_UNINIT_MAX_LEN; | 2928 | max_blocks = EXT_UNINIT_MAX_LEN; |
2940 | 2929 | ||
2941 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ | 2930 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ |
@@ -2966,7 +2955,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2966 | /* try to insert new extent into found leaf and return */ | 2955 | /* try to insert new extent into found leaf and return */ |
2967 | ext4_ext_store_pblock(&newex, newblock); | 2956 | ext4_ext_store_pblock(&newex, newblock); |
2968 | newex.ee_len = cpu_to_le16(ar.len); | 2957 | newex.ee_len = cpu_to_le16(ar.len); |
2969 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */ | 2958 | if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) /* Mark uninitialized */ |
2970 | ext4_ext_mark_uninitialized(&newex); | 2959 | ext4_ext_mark_uninitialized(&newex); |
2971 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | 2960 | err = ext4_ext_insert_extent(handle, inode, path, &newex); |
2972 | if (err) { | 2961 | if (err) { |
@@ -2983,18 +2972,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2983 | newblock = ext_pblock(&newex); | 2972 | newblock = ext_pblock(&newex); |
2984 | allocated = ext4_ext_get_actual_len(&newex); | 2973 | allocated = ext4_ext_get_actual_len(&newex); |
2985 | outnew: | 2974 | outnew: |
2986 | if (extend_disksize) { | ||
2987 | disksize = ((loff_t) iblock + ar.len) << inode->i_blkbits; | ||
2988 | if (disksize > i_size_read(inode)) | ||
2989 | disksize = i_size_read(inode); | ||
2990 | if (disksize > EXT4_I(inode)->i_disksize) | ||
2991 | EXT4_I(inode)->i_disksize = disksize; | ||
2992 | } | ||
2993 | |||
2994 | set_buffer_new(bh_result); | 2975 | set_buffer_new(bh_result); |
2995 | 2976 | ||
2996 | /* Cache only when it is _not_ an uninitialized extent */ | 2977 | /* Cache only when it is _not_ an uninitialized extent */ |
2997 | if (create != EXT4_CREATE_UNINITIALIZED_EXT) | 2978 | if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0) |
2998 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, | 2979 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, |
2999 | EXT4_EXT_CACHE_EXTENT); | 2980 | EXT4_EXT_CACHE_EXTENT); |
3000 | out: | 2981 | out: |
@@ -3150,9 +3131,10 @@ retry: | |||
3150 | ret = PTR_ERR(handle); | 3131 | ret = PTR_ERR(handle); |
3151 | break; | 3132 | break; |
3152 | } | 3133 | } |
3153 | ret = ext4_get_blocks_wrap(handle, inode, block, | 3134 | map_bh.b_state = 0; |
3154 | max_blocks, &map_bh, | 3135 | ret = ext4_get_blocks(handle, inode, block, |
3155 | EXT4_CREATE_UNINITIALIZED_EXT, 0, 0); | 3136 | max_blocks, &map_bh, |
3137 | EXT4_GET_BLOCKS_CREATE_UNINIT_EXT); | ||
3156 | if (ret <= 0) { | 3138 | if (ret <= 0) { |
3157 | #ifdef EXT4FS_DEBUG | 3139 | #ifdef EXT4FS_DEBUG |
3158 | WARN_ON(ret <= 0); | 3140 | WARN_ON(ret <= 0); |
@@ -3195,7 +3177,7 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, | |||
3195 | void *data) | 3177 | void *data) |
3196 | { | 3178 | { |
3197 | struct fiemap_extent_info *fieinfo = data; | 3179 | struct fiemap_extent_info *fieinfo = data; |
3198 | unsigned long blksize_bits = inode->i_sb->s_blocksize_bits; | 3180 | unsigned char blksize_bits = inode->i_sb->s_blocksize_bits; |
3199 | __u64 logical; | 3181 | __u64 logical; |
3200 | __u64 physical; | 3182 | __u64 physical; |
3201 | __u64 length; | 3183 | __u64 length; |
@@ -3242,9 +3224,16 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, | |||
3242 | * | 3224 | * |
3243 | * XXX this might miss a single-block extent at EXT_MAX_BLOCK | 3225 | * XXX this might miss a single-block extent at EXT_MAX_BLOCK |
3244 | */ | 3226 | */ |
3245 | if (logical + length - 1 == EXT_MAX_BLOCK || | 3227 | if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK || |
3246 | ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK) | 3228 | newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK) { |
3229 | loff_t size = i_size_read(inode); | ||
3230 | loff_t bs = EXT4_BLOCK_SIZE(inode->i_sb); | ||
3231 | |||
3247 | flags |= FIEMAP_EXTENT_LAST; | 3232 | flags |= FIEMAP_EXTENT_LAST; |
3233 | if ((flags & FIEMAP_EXTENT_DELALLOC) && | ||
3234 | logical+length > size) | ||
3235 | length = (size - logical + bs - 1) & ~(bs-1); | ||
3236 | } | ||
3248 | 3237 | ||
3249 | error = fiemap_fill_next_extent(fieinfo, logical, physical, | 3238 | error = fiemap_fill_next_extent(fieinfo, logical, physical, |
3250 | length, flags); | 3239 | length, flags); |
@@ -3318,10 +3307,10 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
3318 | * Walk the extent tree gathering extent information. | 3307 | * Walk the extent tree gathering extent information. |
3319 | * ext4_ext_fiemap_cb will push extents back to user. | 3308 | * ext4_ext_fiemap_cb will push extents back to user. |
3320 | */ | 3309 | */ |
3321 | down_write(&EXT4_I(inode)->i_data_sem); | 3310 | down_read(&EXT4_I(inode)->i_data_sem); |
3322 | error = ext4_ext_walk_space(inode, start_blk, len_blks, | 3311 | error = ext4_ext_walk_space(inode, start_blk, len_blks, |
3323 | ext4_ext_fiemap_cb, fieinfo); | 3312 | ext4_ext_fiemap_cb, fieinfo); |
3324 | up_write(&EXT4_I(inode)->i_data_sem); | 3313 | up_read(&EXT4_I(inode)->i_data_sem); |
3325 | } | 3314 | } |
3326 | 3315 | ||
3327 | return error; | 3316 | return error; |