diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 108 |
1 files changed, 87 insertions, 21 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 28dd8eeea6a9..9c6d06dcef8b 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,29 @@ 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 = cpu_to_le16( | ||
3003 | ext4_ext_get_actual_len(ex2)); | ||
3004 | ext4_ext_store_pblock(&zero_ex, | ||
3005 | ext4_ext_pblock(ex2)); | ||
3006 | } else { | ||
2996 | err = ext4_ext_zeroout(inode, ex); | 3007 | err = ext4_ext_zeroout(inode, ex); |
2997 | } else | 3008 | zero_ex.ee_block = ex->ee_block; |
3009 | zero_ex.ee_len = cpu_to_le16( | ||
3010 | ext4_ext_get_actual_len(ex)); | ||
3011 | ext4_ext_store_pblock(&zero_ex, | ||
3012 | ext4_ext_pblock(ex)); | ||
3013 | } | ||
3014 | } else { | ||
2998 | err = ext4_ext_zeroout(inode, &orig_ex); | 3015 | err = ext4_ext_zeroout(inode, &orig_ex); |
3016 | zero_ex.ee_block = orig_ex.ee_block; | ||
3017 | zero_ex.ee_len = cpu_to_le16( | ||
3018 | ext4_ext_get_actual_len(&orig_ex)); | ||
3019 | ext4_ext_store_pblock(&zero_ex, | ||
3020 | ext4_ext_pblock(&orig_ex)); | ||
3021 | } | ||
2999 | 3022 | ||
3000 | if (err) | 3023 | if (err) |
3001 | goto fix_extent_len; | 3024 | goto fix_extent_len; |
@@ -3003,6 +3026,12 @@ static int ext4_split_extent_at(handle_t *handle, | |||
3003 | ex->ee_len = cpu_to_le16(ee_len); | 3026 | ex->ee_len = cpu_to_le16(ee_len); |
3004 | ext4_ext_try_to_merge(handle, inode, path, ex); | 3027 | ext4_ext_try_to_merge(handle, inode, path, ex); |
3005 | err = ext4_ext_dirty(handle, inode, path + path->p_depth); | 3028 | err = ext4_ext_dirty(handle, inode, path + path->p_depth); |
3029 | if (err) | ||
3030 | goto fix_extent_len; | ||
3031 | |||
3032 | /* update extent status tree */ | ||
3033 | err = ext4_es_zeroout(inode, &zero_ex); | ||
3034 | |||
3006 | goto out; | 3035 | goto out; |
3007 | } else if (err) | 3036 | } else if (err) |
3008 | goto fix_extent_len; | 3037 | goto fix_extent_len; |
@@ -3041,6 +3070,7 @@ static int ext4_split_extent(handle_t *handle, | |||
3041 | int err = 0; | 3070 | int err = 0; |
3042 | int uninitialized; | 3071 | int uninitialized; |
3043 | int split_flag1, flags1; | 3072 | int split_flag1, flags1; |
3073 | int allocated = map->m_len; | ||
3044 | 3074 | ||
3045 | depth = ext_depth(inode); | 3075 | depth = ext_depth(inode); |
3046 | ex = path[depth].p_ext; | 3076 | ex = path[depth].p_ext; |
@@ -3060,20 +3090,29 @@ static int ext4_split_extent(handle_t *handle, | |||
3060 | map->m_lblk + map->m_len, split_flag1, flags1); | 3090 | map->m_lblk + map->m_len, split_flag1, flags1); |
3061 | if (err) | 3091 | if (err) |
3062 | goto out; | 3092 | goto out; |
3093 | } else { | ||
3094 | allocated = ee_len - (map->m_lblk - ee_block); | ||
3063 | } | 3095 | } |
3064 | 3096 | /* | |
3097 | * Update path is required because previous ext4_split_extent_at() may | ||
3098 | * result in split of original leaf or extent zeroout. | ||
3099 | */ | ||
3065 | ext4_ext_drop_refs(path); | 3100 | ext4_ext_drop_refs(path); |
3066 | path = ext4_ext_find_extent(inode, map->m_lblk, path); | 3101 | path = ext4_ext_find_extent(inode, map->m_lblk, path); |
3067 | if (IS_ERR(path)) | 3102 | if (IS_ERR(path)) |
3068 | return PTR_ERR(path); | 3103 | return PTR_ERR(path); |
3104 | depth = ext_depth(inode); | ||
3105 | ex = path[depth].p_ext; | ||
3106 | uninitialized = ext4_ext_is_uninitialized(ex); | ||
3107 | split_flag1 = 0; | ||
3069 | 3108 | ||
3070 | if (map->m_lblk >= ee_block) { | 3109 | if (map->m_lblk >= ee_block) { |
3071 | split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT | | 3110 | split_flag1 = split_flag & EXT4_EXT_DATA_VALID2; |
3072 | EXT4_EXT_DATA_VALID2); | 3111 | if (uninitialized) { |
3073 | if (uninitialized) | ||
3074 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; | 3112 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; |
3075 | if (split_flag & EXT4_EXT_MARK_UNINIT2) | 3113 | split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT | |
3076 | split_flag1 |= EXT4_EXT_MARK_UNINIT2; | 3114 | EXT4_EXT_MARK_UNINIT2); |
3115 | } | ||
3077 | err = ext4_split_extent_at(handle, inode, path, | 3116 | err = ext4_split_extent_at(handle, inode, path, |
3078 | map->m_lblk, split_flag1, flags); | 3117 | map->m_lblk, split_flag1, flags); |
3079 | if (err) | 3118 | if (err) |
@@ -3082,7 +3121,7 @@ static int ext4_split_extent(handle_t *handle, | |||
3082 | 3121 | ||
3083 | ext4_ext_show_leaf(inode, path); | 3122 | ext4_ext_show_leaf(inode, path); |
3084 | out: | 3123 | out: |
3085 | return err ? err : map->m_len; | 3124 | return err ? err : allocated; |
3086 | } | 3125 | } |
3087 | 3126 | ||
3088 | /* | 3127 | /* |
@@ -3137,6 +3176,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3137 | ee_block = le32_to_cpu(ex->ee_block); | 3176 | ee_block = le32_to_cpu(ex->ee_block); |
3138 | ee_len = ext4_ext_get_actual_len(ex); | 3177 | ee_len = ext4_ext_get_actual_len(ex); |
3139 | allocated = ee_len - (map->m_lblk - ee_block); | 3178 | allocated = ee_len - (map->m_lblk - ee_block); |
3179 | zero_ex.ee_len = 0; | ||
3140 | 3180 | ||
3141 | trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); | 3181 | trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); |
3142 | 3182 | ||
@@ -3227,13 +3267,16 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3227 | 3267 | ||
3228 | if (EXT4_EXT_MAY_ZEROOUT & split_flag) | 3268 | if (EXT4_EXT_MAY_ZEROOUT & split_flag) |
3229 | max_zeroout = sbi->s_extent_max_zeroout_kb >> | 3269 | max_zeroout = sbi->s_extent_max_zeroout_kb >> |
3230 | inode->i_sb->s_blocksize_bits; | 3270 | (inode->i_sb->s_blocksize_bits - 10); |
3231 | 3271 | ||
3232 | /* If extent is less than s_max_zeroout_kb, zeroout directly */ | 3272 | /* If extent is less than s_max_zeroout_kb, zeroout directly */ |
3233 | if (max_zeroout && (ee_len <= max_zeroout)) { | 3273 | if (max_zeroout && (ee_len <= max_zeroout)) { |
3234 | err = ext4_ext_zeroout(inode, ex); | 3274 | err = ext4_ext_zeroout(inode, ex); |
3235 | if (err) | 3275 | if (err) |
3236 | goto out; | 3276 | goto out; |
3277 | zero_ex.ee_block = ex->ee_block; | ||
3278 | zero_ex.ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)); | ||
3279 | ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); | ||
3237 | 3280 | ||
3238 | err = ext4_ext_get_access(handle, inode, path + depth); | 3281 | err = ext4_ext_get_access(handle, inode, path + depth); |
3239 | if (err) | 3282 | if (err) |
@@ -3292,6 +3335,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3292 | err = allocated; | 3335 | err = allocated; |
3293 | 3336 | ||
3294 | out: | 3337 | out: |
3338 | /* If we have gotten a failure, don't zero out status tree */ | ||
3339 | if (!err) | ||
3340 | err = ext4_es_zeroout(inode, &zero_ex); | ||
3295 | return err ? err : allocated; | 3341 | return err ? err : allocated; |
3296 | } | 3342 | } |
3297 | 3343 | ||
@@ -3374,8 +3420,19 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle, | |||
3374 | "block %llu, max_blocks %u\n", inode->i_ino, | 3420 | "block %llu, max_blocks %u\n", inode->i_ino, |
3375 | (unsigned long long)ee_block, ee_len); | 3421 | (unsigned long long)ee_block, ee_len); |
3376 | 3422 | ||
3377 | /* If extent is larger than requested then split is required */ | 3423 | /* If extent is larger than requested it is a clear sign that we still |
3424 | * have some extent state machine issues left. So extent_split is still | ||
3425 | * required. | ||
3426 | * TODO: Once all related issues will be fixed this situation should be | ||
3427 | * illegal. | ||
3428 | */ | ||
3378 | if (ee_block != map->m_lblk || ee_len > map->m_len) { | 3429 | if (ee_block != map->m_lblk || ee_len > map->m_len) { |
3430 | #ifdef EXT4_DEBUG | ||
3431 | ext4_warning("Inode (%ld) finished: extent logical block %llu," | ||
3432 | " len %u; IO logical block %llu, len %u\n", | ||
3433 | inode->i_ino, (unsigned long long)ee_block, ee_len, | ||
3434 | (unsigned long long)map->m_lblk, map->m_len); | ||
3435 | #endif | ||
3379 | err = ext4_split_unwritten_extents(handle, inode, map, path, | 3436 | err = ext4_split_unwritten_extents(handle, inode, map, path, |
3380 | EXT4_GET_BLOCKS_CONVERT); | 3437 | EXT4_GET_BLOCKS_CONVERT); |
3381 | if (err < 0) | 3438 | if (err < 0) |
@@ -3626,6 +3683,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
3626 | path, map->m_len); | 3683 | path, map->m_len); |
3627 | } else | 3684 | } else |
3628 | err = ret; | 3685 | err = ret; |
3686 | map->m_flags |= EXT4_MAP_MAPPED; | ||
3687 | if (allocated > map->m_len) | ||
3688 | allocated = map->m_len; | ||
3689 | map->m_len = allocated; | ||
3629 | goto out2; | 3690 | goto out2; |
3630 | } | 3691 | } |
3631 | /* buffered IO case */ | 3692 | /* buffered IO case */ |
@@ -3675,6 +3736,7 @@ out: | |||
3675 | allocated - map->m_len); | 3736 | allocated - map->m_len); |
3676 | allocated = map->m_len; | 3737 | allocated = map->m_len; |
3677 | } | 3738 | } |
3739 | map->m_len = allocated; | ||
3678 | 3740 | ||
3679 | /* | 3741 | /* |
3680 | * If we have done fallocate with the offset that is already | 3742 | * If we have done fallocate with the offset that is already |
@@ -4106,9 +4168,6 @@ got_allocated_blocks: | |||
4106 | } | 4168 | } |
4107 | } else { | 4169 | } else { |
4108 | BUG_ON(allocated_clusters < reserved_clusters); | 4170 | 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) { | 4171 | if (reserved_clusters < allocated_clusters) { |
4113 | struct ext4_inode_info *ei = EXT4_I(inode); | 4172 | struct ext4_inode_info *ei = EXT4_I(inode); |
4114 | int reservation = allocated_clusters - | 4173 | int reservation = allocated_clusters - |
@@ -4159,6 +4218,15 @@ got_allocated_blocks: | |||
4159 | ei->i_reserved_data_blocks += reservation; | 4218 | ei->i_reserved_data_blocks += reservation; |
4160 | spin_unlock(&ei->i_block_reservation_lock); | 4219 | spin_unlock(&ei->i_block_reservation_lock); |
4161 | } | 4220 | } |
4221 | /* | ||
4222 | * We will claim quota for all newly allocated blocks. | ||
4223 | * We're updating the reserved space *after* the | ||
4224 | * correction above so we do not accidentally free | ||
4225 | * all the metadata reservation because we might | ||
4226 | * actually need it later on. | ||
4227 | */ | ||
4228 | ext4_da_update_reserve_space(inode, allocated_clusters, | ||
4229 | 1); | ||
4162 | } | 4230 | } |
4163 | } | 4231 | } |
4164 | 4232 | ||
@@ -4368,8 +4436,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
4368 | if (len <= EXT_UNINIT_MAX_LEN << blkbits) | 4436 | if (len <= EXT_UNINIT_MAX_LEN << blkbits) |
4369 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; | 4437 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; |
4370 | 4438 | ||
4371 | /* Prevent race condition between unwritten */ | ||
4372 | ext4_flush_unwritten_io(inode); | ||
4373 | retry: | 4439 | retry: |
4374 | while (ret >= 0 && ret < max_blocks) { | 4440 | while (ret >= 0 && ret < max_blocks) { |
4375 | map.m_lblk = map.m_lblk + ret; | 4441 | map.m_lblk = map.m_lblk + ret; |