|
@@ -2943,6 +2943,10 @@ static int ext4_split_extent_at(handle_t *handle,
|
|
|
newblock = split - ee_block + ext4_ext_pblock(ex);
|
|
|
|
|
|
BUG_ON(split < ee_block || split >= (ee_block + ee_len));
|
|
|
+ BUG_ON(!ext4_ext_is_uninitialized(ex) &&
|
|
|
+ split_flag & (EXT4_EXT_MAY_ZEROOUT |
|
|
|
+ EXT4_EXT_MARK_UNINIT1 |
|
|
|
+ EXT4_EXT_MARK_UNINIT2));
|
|
|
|
|
|
err = ext4_ext_get_access(handle, inode, path + depth);
|
|
|
if (err)
|
|
@@ -3061,19 +3065,26 @@ static int ext4_split_extent(handle_t *handle,
|
|
|
if (err)
|
|
|
goto out;
|
|
|
}
|
|
|
-
|
|
|
+ /*
|
|
|
+ * Update path is required because previous ext4_split_extent_at() may
|
|
|
+ * result in split of original leaf or extent zeroout.
|
|
|
+ */
|
|
|
ext4_ext_drop_refs(path);
|
|
|
path = ext4_ext_find_extent(inode, map->m_lblk, path);
|
|
|
if (IS_ERR(path))
|
|
|
return PTR_ERR(path);
|
|
|
+ depth = ext_depth(inode);
|
|
|
+ ex = path[depth].p_ext;
|
|
|
+ uninitialized = ext4_ext_is_uninitialized(ex);
|
|
|
+ split_flag1 = 0;
|
|
|
|
|
|
if (map->m_lblk >= ee_block) {
|
|
|
- split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT |
|
|
|
- EXT4_EXT_DATA_VALID2);
|
|
|
- if (uninitialized)
|
|
|
+ split_flag1 = split_flag & EXT4_EXT_DATA_VALID2;
|
|
|
+ if (uninitialized) {
|
|
|
split_flag1 |= EXT4_EXT_MARK_UNINIT1;
|
|
|
- if (split_flag & EXT4_EXT_MARK_UNINIT2)
|
|
|
- split_flag1 |= EXT4_EXT_MARK_UNINIT2;
|
|
|
+ split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT |
|
|
|
+ EXT4_EXT_MARK_UNINIT2);
|
|
|
+ }
|
|
|
err = ext4_split_extent_at(handle, inode, path,
|
|
|
map->m_lblk, split_flag1, flags);
|
|
|
if (err)
|