summaryrefslogtreecommitdiff
path: root/fs/f2fs/inode.c
diff options
context:
space:
mode:
authorDaeho Jeong <daehojeong@google.com>2023-02-09 10:18:19 -0800
committerJaegeuk Kim <jaegeuk@kernel.org>2023-02-14 10:08:59 -0800
commita46bebd502fe1a3bd1d22f64cedd93e7e7702693 (patch)
tree0b63e93cd537f5114926bf754814064a283cfc5d /fs/f2fs/inode.c
parent7e986855fe13de2c8290c1102292d8e5f29dd769 (diff)
f2fs: synchronize atomic write aborts
To fix a race condition between atomic write aborts, I use the inode lock and make COW inode to be re-usable thoroughout the whole atomic file inode lifetime. Reported-by: syzbot+823000d23b3400619f7c@syzkaller.appspotmail.com Fixes: 3db1de0e582c ("f2fs: change the current atomic write way") Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/inode.c')
-rw-r--r--fs/f2fs/inode.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 2c250120d5da..7d2e2c0dba65 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -767,11 +767,18 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
void f2fs_evict_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
- nid_t xnid = F2FS_I(inode)->i_xattr_nid;
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+ nid_t xnid = fi->i_xattr_nid;
int err = 0;
f2fs_abort_atomic_write(inode, true);
+ if (fi->cow_inode) {
+ clear_inode_flag(fi->cow_inode, FI_COW_FILE);
+ iput(fi->cow_inode);
+ fi->cow_inode = NULL;
+ }
+
trace_f2fs_evict_inode(inode);
truncate_inode_pages_final(&inode->i_data);
@@ -856,7 +863,7 @@ no_delete:
stat_dec_inline_inode(inode);
stat_dec_compr_inode(inode);
stat_sub_compr_blocks(inode,
- atomic_read(&F2FS_I(inode)->i_compr_blocks));
+ atomic_read(&fi->i_compr_blocks));
if (likely(!f2fs_cp_error(sbi) &&
!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))