[PATCH v2 23/25] ext4: refactor ext4_swap_extents() to reuse extents path

libaokun
2024-08-22T02:40:44Z

The ext4_find_extent() can update the extent path so it doesn't have to
allocate and free path repeatedly, thus reducing the consumption of memory
allocation and freeing in ext4_swap_extents().

Signed-off-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Tested-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
---
fs/ext4/extents.c | 48 ++++++++++++++++++++++-------------------------
1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index bc7b1dc13084..37b36b1abb16 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -5699,25 +5699,21 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
int e1_len, e2_len, len;
int split = 0;

- path1 = ext4_find_extent(inode1, lblk1, NULL, EXT4_EX_NOCACHE);
+ path1 = ext4_find_extent(inode1, lblk1, path1, EXT4_EX_NOCACHE);
if (IS_ERR(path1)) {
*erp = PTR_ERR(path1);
- path1 = NULL;
- finish:
- count = 0;
- goto repeat;
+ goto errout;
}
- path2 = ext4_find_extent(inode2, lblk2, NULL, EXT4_EX_NOCACHE);
+ path2 = ext4_find_extent(inode2, lblk2, path2, EXT4_EX_NOCACHE);
if (IS_ERR(path2)) {
*erp = PTR_ERR(path2);
- path2 = NULL;
- goto finish;
+ goto errout;
}
ex1 = path1[path1->p_depth].p_ext;
ex2 = path2[path2->p_depth].p_ext;
/* Do we have something to swap ? */
if (unlikely(!ex2 || !ex1))
- goto finish;
+ goto errout;

e1_blk = le32_to_cpu(ex1->ee_block);
e2_blk = le32_to_cpu(ex2->ee_block);
@@ -5739,7 +5735,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
next2 = e2_blk;
/* Do we have something to swap */
if (next1 == EXT_MAX_BLOCKS || next2 == EXT_MAX_BLOCKS)
- goto finish;
+ goto errout;
/* Move to the rightest boundary */
len = next1 - lblk1;
if (len < next2 - lblk2)
@@ -5749,7 +5745,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
lblk1 += len;
lblk2 += len;
count -= len;
- goto repeat;
+ continue;
}

/* Prepare left boundary */
@@ -5759,7 +5755,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
path1, lblk1, 0);
if (IS_ERR(path1)) {
*erp = PTR_ERR(path1);
- goto finish;
+ goto errout;
}
}
if (e2_blk < lblk2) {
@@ -5768,13 +5764,13 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
path2, lblk2, 0);
if (IS_ERR(path2)) {
*erp = PTR_ERR(path2);
- goto finish;
+ goto errout;
}
}
/* ext4_split_extent_at() may result in leaf extent split,
* path must to be revalidated. */
if (split)
- goto repeat;
+ continue;

/* Prepare right boundary */
len = count;
@@ -5789,7 +5785,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
path1, lblk1 + len, 0);
if (IS_ERR(path1)) {
*erp = PTR_ERR(path1);
- goto finish;
+ goto errout;
}
}
if (len != e2_len) {
@@ -5798,21 +5794,21 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
path2, lblk2 + len, 0);
if (IS_ERR(path2)) {
*erp = PTR_ERR(path2);
- goto finish;
+ goto errout;
}
}
/* ext4_split_extent_at() may result in leaf extent split,
* path must to be revalidated. */
if (split)
- goto repeat;
+ continue;

BUG_ON(e2_len != e1_len);
*erp = ext4_ext_get_access(handle, inode1, path1 + path1->p_depth);
if (unlikely(*erp))
- goto finish;
+ goto errout;
*erp = ext4_ext_get_access(handle, inode2, path2 + path2->p_depth);
if (unlikely(*erp))
- goto finish;
+ goto errout;

/* Both extents are fully inside boundaries. Swap it now */
tmp_ex = *ex1;
@@ -5830,7 +5826,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
*erp = ext4_ext_dirty(handle, inode2, path2 +
path2->p_depth);
if (unlikely(*erp))
- goto finish;
+ goto errout;
*erp = ext4_ext_dirty(handle, inode1, path1 +
path1->p_depth);
/*
@@ -5840,17 +5836,17 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
* aborted anyway.
*/
if (unlikely(*erp))
- goto finish;
+ goto errout;
+
lblk1 += len;
lblk2 += len;
replaced_count += len;
count -= len;
-
- repeat:
- ext4_free_ext_path(path1);
- ext4_free_ext_path(path2);
- path1 = path2 = NULL;
}
+
+errout:
+ ext4_free_ext_path(path1);
+ ext4_free_ext_path(path2);
return replaced_count;
}

--
2.39.2