Skip to content
Snippets Groups Projects
Commit 4a504128 authored by Qi Han's avatar Qi Han Committed by Jhih-Chen Huang (xWF)
Browse files

BACKPORT: f2fs: compress: fix inconsistent update of i_blocks in...

BACKPORT: f2fs: compress: fix inconsistent update of i_blocks in release_compress_blocks and reserve_compress_blocks

After release a file and subsequently reserve it, the FSCK flag is set
when the file is deleted, as shown in the following backtrace:

F2FS-fs (dm-48): Inconsistent i_blocks, ino:401231, iblocks:1448, sectors:1472
fs_rec_info_write_type+0x58/0x274
f2fs_rec_info_write+0x1c/0x2c
set_sbi_flag+0x74/0x98
dec_valid_block_count+0x150/0x190
f2fs_truncate_data_blocks_range+0x2d4/0x3cc
f2fs_do_truncate_blocks+0x2fc/0x5f0
f2fs_truncate_blocks+0x68/0x100
f2fs_truncate+0x80/0x128
f2fs_evict_inode+0x1a4/0x794
evict+0xd4/0x280
iput+0x238/0x284
do_unlinkat+0x1ac/0x298
__arm64_sys_unlinkat+0x48/0x68
invoke_syscall+0x58/0x11c

For clusters of the following type, i_blocks are decremented by 1 and
i_compr_blocks are incremented by 7 in release_compress_blocks, while
updates to i_blocks and i_compr_blocks are skipped in reserve_compress_blocks.

raw node:
D D D D D D D D
after compress:
C D D D D D D D
after reserve:
C D D D D D D D

Let's update i_blocks and i_compr_blocks properly in reserve_compress_blocks.

Bug: 403145794
Bug: 404077296
Fixes: eb8fbaa5 ("f2fs: compress: fix to check unreleased compressed cluster")
Change-Id: I596af62bbd54941bfc77f30e182db94e81cba59b
Signed-off-by: default avatarQi Han <hanqi@vivo.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
(cherry picked from commit 26413ce1)
(cherry picked from commit 90d49524)
(cherry picked from commit 27895588)
parent 8d713f9e
No related branches found
No related tags found
No related merge requests found
......@@ -3717,7 +3717,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
to_reserved = cluster_size - compr_blocks - reserved;
/* for the case all blocks in cluster were reserved */
if (to_reserved == 1) {
if (reserved && to_reserved == 1) {
dn->ofs_in_node += cluster_size;
goto next;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment