ext4: Fix fallocate error path
Put the old extent details back if we fail to split the uninitialized extent. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
f3f12faa74
commit
95c3889cb8
|
@ -2154,7 +2154,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
|
||||||
ext4_lblk_t iblock,
|
ext4_lblk_t iblock,
|
||||||
unsigned long max_blocks)
|
unsigned long max_blocks)
|
||||||
{
|
{
|
||||||
struct ext4_extent *ex, newex;
|
struct ext4_extent *ex, newex, orig_ex;
|
||||||
struct ext4_extent *ex1 = NULL;
|
struct ext4_extent *ex1 = NULL;
|
||||||
struct ext4_extent *ex2 = NULL;
|
struct ext4_extent *ex2 = NULL;
|
||||||
struct ext4_extent *ex3 = NULL;
|
struct ext4_extent *ex3 = NULL;
|
||||||
|
@ -2173,6 +2173,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
|
||||||
allocated = ee_len - (iblock - ee_block);
|
allocated = ee_len - (iblock - ee_block);
|
||||||
newblock = iblock - ee_block + ext_pblock(ex);
|
newblock = iblock - ee_block + ext_pblock(ex);
|
||||||
ex2 = ex;
|
ex2 = ex;
|
||||||
|
orig_ex.ee_block = ex->ee_block;
|
||||||
|
orig_ex.ee_len = cpu_to_le16(ee_len);
|
||||||
|
ext4_ext_store_pblock(&orig_ex, ext_pblock(ex));
|
||||||
|
|
||||||
err = ext4_ext_get_access(handle, inode, path + depth);
|
err = ext4_ext_get_access(handle, inode, path + depth);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -2201,13 +2204,25 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
|
||||||
ex3->ee_len = cpu_to_le16(allocated - max_blocks);
|
ex3->ee_len = cpu_to_le16(allocated - max_blocks);
|
||||||
ext4_ext_mark_uninitialized(ex3);
|
ext4_ext_mark_uninitialized(ex3);
|
||||||
err = ext4_ext_insert_extent(handle, inode, path, ex3);
|
err = ext4_ext_insert_extent(handle, inode, path, ex3);
|
||||||
if (err)
|
if (err) {
|
||||||
|
ex->ee_block = orig_ex.ee_block;
|
||||||
|
ex->ee_len = orig_ex.ee_len;
|
||||||
|
ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
|
||||||
|
ext4_ext_mark_uninitialized(ex);
|
||||||
|
ext4_ext_dirty(handle, inode, path + depth);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* The depth, and hence eh & ex might change
|
* The depth, and hence eh & ex might change
|
||||||
* as part of the insert above.
|
* as part of the insert above.
|
||||||
*/
|
*/
|
||||||
newdepth = ext_depth(inode);
|
newdepth = ext_depth(inode);
|
||||||
|
/*
|
||||||
|
* update the extent length after successfull insert of the
|
||||||
|
* split extent
|
||||||
|
*/
|
||||||
|
orig_ex.ee_len = cpu_to_le16(ee_len -
|
||||||
|
ext4_ext_get_actual_len(ex3));
|
||||||
if (newdepth != depth) {
|
if (newdepth != depth) {
|
||||||
depth = newdepth;
|
depth = newdepth;
|
||||||
ext4_ext_drop_refs(path);
|
ext4_ext_drop_refs(path);
|
||||||
|
@ -2282,6 +2297,13 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
|
||||||
goto out;
|
goto out;
|
||||||
insert:
|
insert:
|
||||||
err = ext4_ext_insert_extent(handle, inode, path, &newex);
|
err = ext4_ext_insert_extent(handle, inode, path, &newex);
|
||||||
|
if (err) {
|
||||||
|
ex->ee_block = orig_ex.ee_block;
|
||||||
|
ex->ee_len = orig_ex.ee_len;
|
||||||
|
ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
|
||||||
|
ext4_ext_mark_uninitialized(ex);
|
||||||
|
ext4_ext_dirty(handle, inode, path + depth);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
return err ? err : allocated;
|
return err ? err : allocated;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue