[PATCH 6.9 107/374] f2fs: compress: fix to update i_compr_blocks correctly

Greg Kroah-Hartman
2024-06-06T14:09:06Z

From: Chao Yu <chao@kernel.org>

[ Upstream commit 186e7d71534df4589405925caca5597af7626c12 ]

Previously, we account reserved blocks and compressed blocks into
@compr_blocks, then, f2fs_i_compr_blocks_update(,compr_blocks) will
update i_compr_blocks incorrectly, fix it.

Meanwhile, for the case all blocks in cluster were reserved, fix to
update dn->ofs_in_node correctly.

Fixes: eb8fbaa53374 ("f2fs: compress: fix to check unreleased compressed cluster")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/file.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 2566dc8a777de..34becfc142d80 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3645,7 +3645,8 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,

while (count) {
int compr_blocks = 0;
- blkcnt_t reserved;
+ blkcnt_t reserved = 0;
+ blkcnt_t to_reserved;
int ret;

for (i = 0; i < cluster_size; i++) {
@@ -3665,20 +3666,26 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
* fails in release_compress_blocks(), so NEW_ADDR
* is a possible case.
*/
- if (blkaddr == NEW_ADDR ||
- __is_valid_data_blkaddr(blkaddr)) {
+ if (blkaddr == NEW_ADDR) {
+ reserved++;
+ continue;
+ }
+ if (__is_valid_data_blkaddr(blkaddr)) {
compr_blocks++;
continue;
}
}

- reserved = cluster_size - compr_blocks;
+ to_reserved = cluster_size - compr_blocks - reserved;

/* for the case all blocks in cluster were reserved */
- if (reserved == 1)
+ if (to_reserved == 1) {
+ dn->ofs_in_node += cluster_size;
goto next;
+ }

- ret = inc_valid_block_count(sbi, dn->inode, &reserved, false);
+ ret = inc_valid_block_count(sbi, dn->inode,
+ &to_reserved, false);
if (unlikely(ret))
return ret;

@@ -3689,7 +3696,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,

f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true);

- *reserved_blocks += reserved;
+ *reserved_blocks += to_reserved;
next:
count -= cluster_size;
}
--
2.43.0