diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/extents.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 372b2cbee07e..bef194a14437 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2943,6 +2943,10 @@ static int ext4_split_extent_at(handle_t *handle, | |||
2943 | newblock = split - ee_block + ext4_ext_pblock(ex); | 2943 | newblock = split - ee_block + ext4_ext_pblock(ex); |
2944 | 2944 | ||
2945 | BUG_ON(split < ee_block || split >= (ee_block + ee_len)); | 2945 | BUG_ON(split < ee_block || split >= (ee_block + ee_len)); |
2946 | BUG_ON(!ext4_ext_is_uninitialized(ex) && | ||
2947 | split_flag & (EXT4_EXT_MAY_ZEROOUT | | ||
2948 | EXT4_EXT_MARK_UNINIT1 | | ||
2949 | EXT4_EXT_MARK_UNINIT2)); | ||
2946 | 2950 | ||
2947 | err = ext4_ext_get_access(handle, inode, path + depth); | 2951 | err = ext4_ext_get_access(handle, inode, path + depth); |
2948 | if (err) | 2952 | if (err) |
@@ -3061,19 +3065,26 @@ static int ext4_split_extent(handle_t *handle, | |||
3061 | if (err) | 3065 | if (err) |
3062 | goto out; | 3066 | goto out; |
3063 | } | 3067 | } |
3064 | 3068 | /* | |
3069 | * Update path is required because previous ext4_split_extent_at() may | ||
3070 | * result in split of original leaf or extent zeroout. | ||
3071 | */ | ||
3065 | ext4_ext_drop_refs(path); | 3072 | ext4_ext_drop_refs(path); |
3066 | path = ext4_ext_find_extent(inode, map->m_lblk, path); | 3073 | path = ext4_ext_find_extent(inode, map->m_lblk, path); |
3067 | if (IS_ERR(path)) | 3074 | if (IS_ERR(path)) |
3068 | return PTR_ERR(path); | 3075 | return PTR_ERR(path); |
3076 | depth = ext_depth(inode); | ||
3077 | ex = path[depth].p_ext; | ||
3078 | uninitialized = ext4_ext_is_uninitialized(ex); | ||
3079 | split_flag1 = 0; | ||
3069 | 3080 | ||
3070 | if (map->m_lblk >= ee_block) { | 3081 | if (map->m_lblk >= ee_block) { |
3071 | split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT | | 3082 | split_flag1 = split_flag & EXT4_EXT_DATA_VALID2; |
3072 | EXT4_EXT_DATA_VALID2); | 3083 | if (uninitialized) { |
3073 | if (uninitialized) | ||
3074 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; | 3084 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; |
3075 | if (split_flag & EXT4_EXT_MARK_UNINIT2) | 3085 | split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT | |
3076 | split_flag1 |= EXT4_EXT_MARK_UNINIT2; | 3086 | EXT4_EXT_MARK_UNINIT2); |
3087 | } | ||
3077 | err = ext4_split_extent_at(handle, inode, path, | 3088 | err = ext4_split_extent_at(handle, inode, path, |
3078 | map->m_lblk, split_flag1, flags); | 3089 | map->m_lblk, split_flag1, flags); |
3079 | if (err) | 3090 | if (err) |