Skip to content

Commit

Permalink
f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ c…
Browse files Browse the repository at this point in the history
…p_rwsem lock

[ Upstream commit 0a4ed2d ]

It needs to cover {reserve,release}_compress_blocks() w/ cp_rwsem lock
to avoid racing with checkpoint, otherwise, filesystem metadata including
blkaddr in dnode, inode fields and .total_valid_block_count may be
corrupted after SPO case.

Fixes: ef8d563 ("f2fs: introduce F2FS_IOC_RELEASE_COMPRESS_BLOCKS")
Fixes: c75488f ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
chaseyu authored and gregkh committed Jun 16, 2024
1 parent 8a8b95b commit b5bac43
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions fs/f2fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -3490,9 +3490,12 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
struct dnode_of_data dn;
pgoff_t end_offset, count;

f2fs_lock_op(sbi);

set_new_dnode(&dn, inode, NULL, NULL, 0);
ret = f2fs_get_dnode_of_data(&dn, page_idx, LOOKUP_NODE);
if (ret) {
f2fs_unlock_op(sbi);
if (ret == -ENOENT) {
page_idx = f2fs_get_next_page_offset(&dn,
page_idx);
Expand All @@ -3510,6 +3513,8 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)

f2fs_put_dnode(&dn);

f2fs_unlock_op(sbi);

if (ret < 0)
break;

Expand Down Expand Up @@ -3652,9 +3657,12 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
struct dnode_of_data dn;
pgoff_t end_offset, count;

f2fs_lock_op(sbi);

set_new_dnode(&dn, inode, NULL, NULL, 0);
ret = f2fs_get_dnode_of_data(&dn, page_idx, LOOKUP_NODE);
if (ret) {
f2fs_unlock_op(sbi);
if (ret == -ENOENT) {
page_idx = f2fs_get_next_page_offset(&dn,
page_idx);
Expand All @@ -3672,6 +3680,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)

f2fs_put_dnode(&dn);

f2fs_unlock_op(sbi);

if (ret < 0)
break;

Expand Down

0 comments on commit b5bac43

Please sign in to comment.