diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d83a21998ec2..edda2ff72073 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3862,6 +3862,7 @@ static int prepare_atomic_write_begin(struct f2fs_sb_info *sbi, pgoff_t index = folio->index; int err = 0; block_t ori_blk_addr = NULL_ADDR; + bool cow_has_reserved_block = false; /* If pos is beyond the end of file, reserve a new block in COW inode */ if ((pos & PAGE_MASK) >= i_size_read(inode)) @@ -3871,9 +3872,11 @@ static int prepare_atomic_write_begin(struct f2fs_sb_info *sbi, err = __find_data_block(cow_inode, index, blk_addr); if (err) { return err; - } else if (*blk_addr != NULL_ADDR) { + } else if (__is_valid_data_blkaddr(*blk_addr)) { *use_cow = true; return 0; + } else if (*blk_addr == NEW_ADDR) { + cow_has_reserved_block = true; } if (is_inode_flag_set(inode, FI_ATOMIC_REPLACE)) @@ -3886,10 +3889,13 @@ static int prepare_atomic_write_begin(struct f2fs_sb_info *sbi, reserve_block: /* Finally, we should reserve a new block in COW inode for the update */ - err = __reserve_data_block(cow_inode, index, blk_addr, node_changed); - if (err) - return err; - inc_atomic_write_cnt(inode); + if (!cow_has_reserved_block) { + err = __reserve_data_block(cow_inode, index, blk_addr, + node_changed); + if (err) + return err; + inc_atomic_write_cnt(inode); + } if (ori_blk_addr != NULL_ADDR) *blk_addr = ori_blk_addr;