ext4: ensure enough credits in ext4_ext_shift_path_extents
commit 4268496e48dc681cfa53b92357314b5d7221e625 upstream. Like ext4_ext_rm_leaf, we can ensure that there are enough credits before every call that will consume credits. As part of this fix we fold the functionality of ext4_access_path() into ext4_ext_shift_path_extents(). This change is needed as a preparation for the next bugfix patch. Cc: stable@kernel.org Link: https://lore.kernel.org/r/20210903062748.4118886-3-yangerkun@huawei.com Signed-off-by: yangerkun <yangerkun@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
aa21b7e3d3
commit
4089432dc0
@@ -4970,36 +4970,6 @@ int ext4_get_es_cache(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
|||||||
return ext4_fill_es_cache_info(inode, start_blk, len_blks, fieinfo);
|
return ext4_fill_es_cache_info(inode, start_blk, len_blks, fieinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ext4_access_path:
|
|
||||||
* Function to access the path buffer for marking it dirty.
|
|
||||||
* It also checks if there are sufficient credits left in the journal handle
|
|
||||||
* to update path.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
ext4_access_path(handle_t *handle, struct inode *inode,
|
|
||||||
struct ext4_ext_path *path)
|
|
||||||
{
|
|
||||||
int credits, err;
|
|
||||||
|
|
||||||
if (!ext4_handle_valid(handle))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if need to extend journal credits
|
|
||||||
* 3 for leaf, sb, and inode plus 2 (bmap and group
|
|
||||||
* descriptor) for each block group; assume two block
|
|
||||||
* groups
|
|
||||||
*/
|
|
||||||
credits = ext4_writepage_trans_blocks(inode);
|
|
||||||
err = ext4_datasem_ensure_credits(handle, inode, 7, credits, 0);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
err = ext4_ext_get_access(handle, inode, path);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ext4_ext_shift_path_extents:
|
* ext4_ext_shift_path_extents:
|
||||||
* Shift the extents of a path structure lying between path[depth].p_ext
|
* Shift the extents of a path structure lying between path[depth].p_ext
|
||||||
@@ -5014,6 +4984,7 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift,
|
|||||||
int depth, err = 0;
|
int depth, err = 0;
|
||||||
struct ext4_extent *ex_start, *ex_last;
|
struct ext4_extent *ex_start, *ex_last;
|
||||||
bool update = false;
|
bool update = false;
|
||||||
|
int credits, restart_credits;
|
||||||
depth = path->p_depth;
|
depth = path->p_depth;
|
||||||
|
|
||||||
while (depth >= 0) {
|
while (depth >= 0) {
|
||||||
@@ -5023,13 +4994,23 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift,
|
|||||||
return -EFSCORRUPTED;
|
return -EFSCORRUPTED;
|
||||||
|
|
||||||
ex_last = EXT_LAST_EXTENT(path[depth].p_hdr);
|
ex_last = EXT_LAST_EXTENT(path[depth].p_hdr);
|
||||||
|
/* leaf + sb + inode */
|
||||||
|
credits = 3;
|
||||||
|
if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) {
|
||||||
|
update = true;
|
||||||
|
/* extent tree + sb + inode */
|
||||||
|
credits = depth + 2;
|
||||||
|
}
|
||||||
|
|
||||||
err = ext4_access_path(handle, inode, path + depth);
|
restart_credits = ext4_writepage_trans_blocks(inode);
|
||||||
|
err = ext4_datasem_ensure_credits(handle, inode, credits,
|
||||||
|
restart_credits, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr))
|
err = ext4_ext_get_access(handle, inode, path + depth);
|
||||||
update = true;
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
while (ex_start <= ex_last) {
|
while (ex_start <= ex_last) {
|
||||||
if (SHIFT == SHIFT_LEFT) {
|
if (SHIFT == SHIFT_LEFT) {
|
||||||
@@ -5060,7 +5041,7 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update index too */
|
/* Update index too */
|
||||||
err = ext4_access_path(handle, inode, path + depth);
|
err = ext4_ext_get_access(handle, inode, path + depth);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user