summaryrefslogtreecommitdiff
path: root/fs/ext4
diff options
context:
space:
mode:
authorBaokun Li <libaokun1@huawei.com>2024-08-22 10:35:43 +0800
committerTheodore Ts'o <tytso@mit.edu>2024-09-03 22:12:18 -0400
commita2c613b8c4860d5e70010e7391fff727c5d96bab (patch)
tree2396ab85ce86a9287e8c001d959e03284fa1c057 /fs/ext4
parent4191eefef978d734fa8249bede3f9b02a85aa3c0 (diff)
ext4: refactor ext4_swap_extents() to reuse extents path
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> Link: https://patch.msgid.link/20240822023545.1994557-24-libaokun@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/extents.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index dbadf2aa4376..e671ad642cfb 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -5663,25 +5663,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);
@@ -5703,7 +5699,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)
@@ -5713,7 +5709,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
lblk1 += len;
lblk2 += len;
count -= len;
- goto repeat;
+ continue;
}
/* Prepare left boundary */
@@ -5723,7 +5719,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) {
@@ -5732,13 +5728,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;
@@ -5753,7 +5749,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) {
@@ -5762,21 +5758,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;
@@ -5794,7 +5790,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);
/*
@@ -5804,17 +5800,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;
}