diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 105 |
1 files changed, 84 insertions, 21 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 28dd8eeea6a9..56efcaadf848 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1584,10 +1584,12 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | |||
1584 | unsigned short ext1_ee_len, ext2_ee_len, max_len; | 1584 | unsigned short ext1_ee_len, ext2_ee_len, max_len; |
1585 | 1585 | ||
1586 | /* | 1586 | /* |
1587 | * Make sure that either both extents are uninitialized, or | 1587 | * Make sure that both extents are initialized. We don't merge |
1588 | * both are _not_. | 1588 | * uninitialized extents so that we can be sure that end_io code has |
1589 | * the extent that was written properly split out and conversion to | ||
1590 | * initialized is trivial. | ||
1589 | */ | 1591 | */ |
1590 | if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2)) | 1592 | if (ext4_ext_is_uninitialized(ex1) || ext4_ext_is_uninitialized(ex2)) |
1591 | return 0; | 1593 | return 0; |
1592 | 1594 | ||
1593 | if (ext4_ext_is_uninitialized(ex1)) | 1595 | if (ext4_ext_is_uninitialized(ex1)) |
@@ -2923,7 +2925,7 @@ static int ext4_split_extent_at(handle_t *handle, | |||
2923 | { | 2925 | { |
2924 | ext4_fsblk_t newblock; | 2926 | ext4_fsblk_t newblock; |
2925 | ext4_lblk_t ee_block; | 2927 | ext4_lblk_t ee_block; |
2926 | struct ext4_extent *ex, newex, orig_ex; | 2928 | struct ext4_extent *ex, newex, orig_ex, zero_ex; |
2927 | struct ext4_extent *ex2 = NULL; | 2929 | struct ext4_extent *ex2 = NULL; |
2928 | unsigned int ee_len, depth; | 2930 | unsigned int ee_len, depth; |
2929 | int err = 0; | 2931 | int err = 0; |
@@ -2943,6 +2945,10 @@ static int ext4_split_extent_at(handle_t *handle, | |||
2943 | newblock = split - ee_block + ext4_ext_pblock(ex); | 2945 | newblock = split - ee_block + ext4_ext_pblock(ex); |
2944 | 2946 | ||
2945 | BUG_ON(split < ee_block || split >= (ee_block + ee_len)); | 2947 | BUG_ON(split < ee_block || split >= (ee_block + ee_len)); |
2948 | BUG_ON(!ext4_ext_is_uninitialized(ex) && | ||
2949 | split_flag & (EXT4_EXT_MAY_ZEROOUT | | ||
2950 | EXT4_EXT_MARK_UNINIT1 | | ||
2951 | EXT4_EXT_MARK_UNINIT2)); | ||
2946 | 2952 | ||
2947 | err = ext4_ext_get_access(handle, inode, path + depth); | 2953 | err = ext4_ext_get_access(handle, inode, path + depth); |
2948 | if (err) | 2954 | if (err) |
@@ -2990,12 +2996,26 @@ static int ext4_split_extent_at(handle_t *handle, | |||
2990 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); | 2996 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); |
2991 | if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { | 2997 | if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { |
2992 | if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { | 2998 | if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { |
2993 | if (split_flag & EXT4_EXT_DATA_VALID1) | 2999 | if (split_flag & EXT4_EXT_DATA_VALID1) { |
2994 | err = ext4_ext_zeroout(inode, ex2); | 3000 | err = ext4_ext_zeroout(inode, ex2); |
2995 | else | 3001 | zero_ex.ee_block = ex2->ee_block; |
3002 | zero_ex.ee_len = ext4_ext_get_actual_len(ex2); | ||
3003 | ext4_ext_store_pblock(&zero_ex, | ||
3004 | ext4_ext_pblock(ex2)); | ||
3005 | } else { | ||
2996 | err = ext4_ext_zeroout(inode, ex); | 3006 | err = ext4_ext_zeroout(inode, ex); |
2997 | } else | 3007 | zero_ex.ee_block = ex->ee_block; |
3008 | zero_ex.ee_len = ext4_ext_get_actual_len(ex); | ||
3009 | ext4_ext_store_pblock(&zero_ex, | ||
3010 | ext4_ext_pblock(ex)); | ||
3011 | } | ||
3012 | } else { | ||
2998 | err = ext4_ext_zeroout(inode, &orig_ex); | 3013 | err = ext4_ext_zeroout(inode, &orig_ex); |
3014 | zero_ex.ee_block = orig_ex.ee_block; | ||
3015 | zero_ex.ee_len = ext4_ext_get_actual_len(&orig_ex); | ||
3016 | ext4_ext_store_pblock(&zero_ex, | ||
3017 | ext4_ext_pblock(&orig_ex)); | ||
3018 | } | ||
2999 | 3019 | ||
3000 | if (err) | 3020 | if (err) |
3001 | goto fix_extent_len; | 3021 | goto fix_extent_len; |
@@ -3003,6 +3023,12 @@ static int ext4_split_extent_at(handle_t *handle, | |||
3003 | ex->ee_len = cpu_to_le16(ee_len); | 3023 | ex->ee_len = cpu_to_le16(ee_len); |
3004 | ext4_ext_try_to_merge(handle, inode, path, ex); | 3024 | ext4_ext_try_to_merge(handle, inode, path, ex); |
3005 | err = ext4_ext_dirty(handle, inode, path + path->p_depth); | 3025 | err = ext4_ext_dirty(handle, inode, path + path->p_depth); |
3026 | if (err) | ||
3027 | goto fix_extent_len; | ||
3028 | |||
3029 | /* update extent status tree */ | ||
3030 | err = ext4_es_zeroout(inode, &zero_ex); | ||
3031 | |||
3006 | goto out; | 3032 | goto out; |
3007 | } else if (err) | 3033 | } else if (err) |
3008 | goto fix_extent_len; | 3034 | goto fix_extent_len; |
@@ -3041,6 +3067,7 @@ static int ext4_split_extent(handle_t *handle, | |||
3041 | int err = 0; | 3067 | int err = 0; |
3042 | int uninitialized; | 3068 | int uninitialized; |
3043 | int split_flag1, flags1; | 3069 | int split_flag1, flags1; |
3070 | int allocated = map->m_len; | ||
3044 | 3071 | ||
3045 | depth = ext_depth(inode); | 3072 | depth = ext_depth(inode); |
3046 | ex = path[depth].p_ext; | 3073 | ex = path[depth].p_ext; |
@@ -3060,20 +3087,29 @@ static int ext4_split_extent(handle_t *handle, | |||
3060 | map->m_lblk + map->m_len, split_flag1, flags1); | 3087 | map->m_lblk + map->m_len, split_flag1, flags1); |
3061 | if (err) | 3088 | if (err) |
3062 | goto out; | 3089 | goto out; |
3090 | } else { | ||
3091 | allocated = ee_len - (map->m_lblk - ee_block); | ||
3063 | } | 3092 | } |
3064 | 3093 | /* | |
3094 | * Update path is required because previous ext4_split_extent_at() may | ||
3095 | * result in split of original leaf or extent zeroout. | ||
3096 | */ | ||
3065 | ext4_ext_drop_refs(path); | 3097 | ext4_ext_drop_refs(path); |
3066 | path = ext4_ext_find_extent(inode, map->m_lblk, path); | 3098 | path = ext4_ext_find_extent(inode, map->m_lblk, path); |
3067 | if (IS_ERR(path)) | 3099 | if (IS_ERR(path)) |
3068 | return PTR_ERR(path); | 3100 | return PTR_ERR(path); |
3101 | depth = ext_depth(inode); | ||
3102 | ex = path[depth].p_ext; | ||
3103 | uninitialized = ext4_ext_is_uninitialized(ex); | ||
3104 | split_flag1 = 0; | ||
3069 | 3105 | ||
3070 | if (map->m_lblk >= ee_block) { | 3106 | if (map->m_lblk >= ee_block) { |
3071 | split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT | | 3107 | split_flag1 = split_flag & EXT4_EXT_DATA_VALID2; |
3072 | EXT4_EXT_DATA_VALID2); | 3108 | if (uninitialized) { |
3073 | if (uninitialized) | ||
3074 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; | 3109 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; |
3075 | if (split_flag & EXT4_EXT_MARK_UNINIT2) | 3110 | split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT | |
3076 | split_flag1 |= EXT4_EXT_MARK_UNINIT2; | 3111 | EXT4_EXT_MARK_UNINIT2); |
3112 | } | ||
3077 | err = ext4_split_extent_at(handle, inode, path, | 3113 | err = ext4_split_extent_at(handle, inode, path, |
3078 | map->m_lblk, split_flag1, flags); | 3114 | map->m_lblk, split_flag1, flags); |
3079 | if (err) | 3115 | if (err) |
@@ -3082,7 +3118,7 @@ static int ext4_split_extent(handle_t *handle, | |||
3082 | 3118 | ||
3083 | ext4_ext_show_leaf(inode, path); | 3119 | ext4_ext_show_leaf(inode, path); |
3084 | out: | 3120 | out: |
3085 | return err ? err : map->m_len; | 3121 | return err ? err : allocated; |
3086 | } | 3122 | } |
3087 | 3123 | ||
3088 | /* | 3124 | /* |
@@ -3137,6 +3173,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3137 | ee_block = le32_to_cpu(ex->ee_block); | 3173 | ee_block = le32_to_cpu(ex->ee_block); |
3138 | ee_len = ext4_ext_get_actual_len(ex); | 3174 | ee_len = ext4_ext_get_actual_len(ex); |
3139 | allocated = ee_len - (map->m_lblk - ee_block); | 3175 | allocated = ee_len - (map->m_lblk - ee_block); |
3176 | zero_ex.ee_len = 0; | ||
3140 | 3177 | ||
3141 | trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); | 3178 | trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); |
3142 | 3179 | ||
@@ -3227,13 +3264,16 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3227 | 3264 | ||
3228 | if (EXT4_EXT_MAY_ZEROOUT & split_flag) | 3265 | if (EXT4_EXT_MAY_ZEROOUT & split_flag) |
3229 | max_zeroout = sbi->s_extent_max_zeroout_kb >> | 3266 | max_zeroout = sbi->s_extent_max_zeroout_kb >> |
3230 | inode->i_sb->s_blocksize_bits; | 3267 | (inode->i_sb->s_blocksize_bits - 10); |
3231 | 3268 | ||
3232 | /* If extent is less than s_max_zeroout_kb, zeroout directly */ | 3269 | /* If extent is less than s_max_zeroout_kb, zeroout directly */ |
3233 | if (max_zeroout && (ee_len <= max_zeroout)) { | 3270 | if (max_zeroout && (ee_len <= max_zeroout)) { |
3234 | err = ext4_ext_zeroout(inode, ex); | 3271 | err = ext4_ext_zeroout(inode, ex); |
3235 | if (err) | 3272 | if (err) |
3236 | goto out; | 3273 | goto out; |
3274 | zero_ex.ee_block = ex->ee_block; | ||
3275 | zero_ex.ee_len = ext4_ext_get_actual_len(ex); | ||
3276 | ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); | ||
3237 | 3277 | ||
3238 | err = ext4_ext_get_access(handle, inode, path + depth); | 3278 | err = ext4_ext_get_access(handle, inode, path + depth); |
3239 | if (err) | 3279 | if (err) |
@@ -3292,6 +3332,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3292 | err = allocated; | 3332 | err = allocated; |
3293 | 3333 | ||
3294 | out: | 3334 | out: |
3335 | /* If we have gotten a failure, don't zero out status tree */ | ||
3336 | if (!err) | ||
3337 | err = ext4_es_zeroout(inode, &zero_ex); | ||
3295 | return err ? err : allocated; | 3338 | return err ? err : allocated; |
3296 | } | 3339 | } |
3297 | 3340 | ||
@@ -3374,8 +3417,19 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle, | |||
3374 | "block %llu, max_blocks %u\n", inode->i_ino, | 3417 | "block %llu, max_blocks %u\n", inode->i_ino, |
3375 | (unsigned long long)ee_block, ee_len); | 3418 | (unsigned long long)ee_block, ee_len); |
3376 | 3419 | ||
3377 | /* If extent is larger than requested then split is required */ | 3420 | /* If extent is larger than requested it is a clear sign that we still |
3421 | * have some extent state machine issues left. So extent_split is still | ||
3422 | * required. | ||
3423 | * TODO: Once all related issues will be fixed this situation should be | ||
3424 | * illegal. | ||
3425 | */ | ||
3378 | if (ee_block != map->m_lblk || ee_len > map->m_len) { | 3426 | if (ee_block != map->m_lblk || ee_len > map->m_len) { |
3427 | #ifdef EXT4_DEBUG | ||
3428 | ext4_warning("Inode (%ld) finished: extent logical block %llu," | ||
3429 | " len %u; IO logical block %llu, len %u\n", | ||
3430 | inode->i_ino, (unsigned long long)ee_block, ee_len, | ||
3431 | (unsigned long long)map->m_lblk, map->m_len); | ||
3432 | #endif | ||
3379 | err = ext4_split_unwritten_extents(handle, inode, map, path, | 3433 | err = ext4_split_unwritten_extents(handle, inode, map, path, |
3380 | EXT4_GET_BLOCKS_CONVERT); | 3434 | EXT4_GET_BLOCKS_CONVERT); |
3381 | if (err < 0) | 3435 | if (err < 0) |
@@ -3626,6 +3680,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
3626 | path, map->m_len); | 3680 | path, map->m_len); |
3627 | } else | 3681 | } else |
3628 | err = ret; | 3682 | err = ret; |
3683 | map->m_flags |= EXT4_MAP_MAPPED; | ||
3684 | if (allocated > map->m_len) | ||
3685 | allocated = map->m_len; | ||
3686 | map->m_len = allocated; | ||
3629 | goto out2; | 3687 | goto out2; |
3630 | } | 3688 | } |
3631 | /* buffered IO case */ | 3689 | /* buffered IO case */ |
@@ -3675,6 +3733,7 @@ out: | |||
3675 | allocated - map->m_len); | 3733 | allocated - map->m_len); |
3676 | allocated = map->m_len; | 3734 | allocated = map->m_len; |
3677 | } | 3735 | } |
3736 | map->m_len = allocated; | ||
3678 | 3737 | ||
3679 | /* | 3738 | /* |
3680 | * If we have done fallocate with the offset that is already | 3739 | * If we have done fallocate with the offset that is already |
@@ -4106,9 +4165,6 @@ got_allocated_blocks: | |||
4106 | } | 4165 | } |
4107 | } else { | 4166 | } else { |
4108 | BUG_ON(allocated_clusters < reserved_clusters); | 4167 | BUG_ON(allocated_clusters < reserved_clusters); |
4109 | /* We will claim quota for all newly allocated blocks.*/ | ||
4110 | ext4_da_update_reserve_space(inode, allocated_clusters, | ||
4111 | 1); | ||
4112 | if (reserved_clusters < allocated_clusters) { | 4168 | if (reserved_clusters < allocated_clusters) { |
4113 | struct ext4_inode_info *ei = EXT4_I(inode); | 4169 | struct ext4_inode_info *ei = EXT4_I(inode); |
4114 | int reservation = allocated_clusters - | 4170 | int reservation = allocated_clusters - |
@@ -4159,6 +4215,15 @@ got_allocated_blocks: | |||
4159 | ei->i_reserved_data_blocks += reservation; | 4215 | ei->i_reserved_data_blocks += reservation; |
4160 | spin_unlock(&ei->i_block_reservation_lock); | 4216 | spin_unlock(&ei->i_block_reservation_lock); |
4161 | } | 4217 | } |
4218 | /* | ||
4219 | * We will claim quota for all newly allocated blocks. | ||
4220 | * We're updating the reserved space *after* the | ||
4221 | * correction above so we do not accidentally free | ||
4222 | * all the metadata reservation because we might | ||
4223 | * actually need it later on. | ||
4224 | */ | ||
4225 | ext4_da_update_reserve_space(inode, allocated_clusters, | ||
4226 | 1); | ||
4162 | } | 4227 | } |
4163 | } | 4228 | } |
4164 | 4229 | ||
@@ -4368,8 +4433,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
4368 | if (len <= EXT_UNINIT_MAX_LEN << blkbits) | 4433 | if (len <= EXT_UNINIT_MAX_LEN << blkbits) |
4369 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; | 4434 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; |
4370 | 4435 | ||
4371 | /* Prevent race condition between unwritten */ | ||
4372 | ext4_flush_unwritten_io(inode); | ||
4373 | retry: | 4436 | retry: |
4374 | while (ret >= 0 && ret < max_blocks) { | 4437 | while (ret >= 0 && ret < max_blocks) { |
4375 | map.m_lblk = map.m_lblk + ret; | 4438 | map.m_lblk = map.m_lblk + ret; |