[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230913021148.1181646-5-enwlinux@gmail.com>
Date: Tue, 12 Sep 2023 22:11:46 -0400
From: Eric Whitney <enwlinux@...il.com>
To: linux-ext4@...r.kernel.org
Cc: tytso@....edu, Eric Whitney <enwlinux@...il.com>
Subject: [PATCH 4/6] ext4: consolidate partial cluster initialization
Pull the code used to initialize a partial cluster into a single
location to improve readability and to minimize the disturbance on
other code. Take advantage of the change to track partial clusters
in the logical space to use a more efficient means to search for a
block adjacent to the block range to be removed.
Signed-off-by: Eric Whitney <enwlinux@...il.com>
---
fs/ext4/extents.c | 70 +++++++++++++++++------------------------------
1 file changed, 25 insertions(+), 45 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 793a9437be9f..a0c9e37ef804 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2641,17 +2641,6 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
/* If this extent is beyond the end of the hole, skip it */
if (end < ex_ee_block) {
- /*
- * We're going to skip this extent and move to another,
- * so note that its first cluster is in use to avoid
- * freeing it when removing blocks. Eventually, the
- * right edge of the truncated/punched region will
- * be just to the left.
- */
- if (sbi->s_cluster_ratio > 1) {
- partial->lblk = ex_ee_block;
- partial->state = keep;
- }
ex--;
ex_ee_block = le32_to_cpu(ex->ee_block);
ex_ee_len = ext4_ext_get_actual_len(ex);
@@ -2812,10 +2801,6 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
handle_t *handle;
int i = 0, err = 0;
- partial.pclu = 0;
- partial.lblk = 0;
- partial.state = none;
-
ext_debug(inode, "truncate since %u to %u\n", start, end);
/* probably first extent we're gonna free will be last in block */
@@ -2825,6 +2810,13 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
if (IS_ERR(handle))
return PTR_ERR(handle);
+ /* state never changes for non-bigalloc file systems */
+ partial.state = none;
+ if (sbi->s_cluster_ratio > 1) {
+ partial.start_lclu = EXT4_B2C(sbi, start);
+ partial.end_lclu = EXT4_B2C(sbi, end);
+ }
+
again:
trace_ext4_ext_remove_space(inode, start, end, depth);
@@ -2838,7 +2830,6 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
if (end < EXT_MAX_BLOCKS - 1) {
struct ext4_extent *ex;
ext4_lblk_t ee_block, ex_end, lblk;
- ext4_fsblk_t pblk;
/* find extent for or closest extent to this block */
path = ext4_find_extent(inode, end, NULL,
@@ -2871,16 +2862,6 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
*/
if (end >= ee_block && end < ex_end) {
- /*
- * If we're going to split the extent, note that
- * the cluster containing the block after 'end' is
- * in use to avoid freeing it when removing blocks.
- */
- if (sbi->s_cluster_ratio > 1) {
- partial.lblk = end + 1;
- partial.state = keep;
- }
-
/*
* Split the extent in two so that 'end' is the last
* block in the first new extent. Also we should not
@@ -2891,27 +2872,26 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
end + 1, 1);
if (err < 0)
goto out;
+ }
- } else if (sbi->s_cluster_ratio > 1 && end >= ex_end &&
- partial.state == none) {
- /*
- * If we're punching, there's an extent to the right.
- * If the partial cluster hasn't been set, set it to
- * that extent's first cluster and its state to keep
- * so it won't be freed should it contain blocks to be
- * removed. If it's already set (free/keep), we're
- * retrying and keep the original partial cluster info
- * so a cluster marked free as a result of earlier
- * extent removal is not lost.
- */
- lblk = ex_end + 1;
- err = ext4_ext_search_right(inode, path, &lblk, &pblk,
- NULL);
- if (err < 0)
- goto out;
- if (pblk) {
- partial.lblk = lblk;
+ /*
+ * if there's a block following the space to be removed
+ * in a bigalloc file system note that the cluster
+ * containing it must not be freed
+ */
+ if (sbi->s_cluster_ratio > 1 && partial.state == none) {
+ if (end < ee_block) {
+ partial.lblk = ee_block;
partial.state = keep;
+ } else if (end >= ee_block && end < ex_end) {
+ partial.lblk = end + 1;
+ partial.state = keep;
+ } else if (end >= ex_end) {
+ lblk = ext4_ext_next_allocated_block(path);
+ if (lblk != EXT_MAX_BLOCKS) {
+ partial.lblk = lblk;
+ partial.state = keep;
+ }
}
}
}
--
2.30.2
Powered by blists - more mailing lists