diff options
author | Chao Yu <chao@kernel.org> | 2024-03-26 12:28:45 +0100 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2024-03-30 00:54:42 +0100 |
commit | d3876e34e7e789e2cbdd782360fef2a777391082 (patch) | |
tree | d95486d1d6651823c7d9d3bc5581ad2e094a5474 /fs/f2fs | |
parent | f2fs: support to map continuous holes or preallocated address (diff) | |
download | linux-d3876e34e7e789e2cbdd782360fef2a777391082.tar.xz linux-d3876e34e7e789e2cbdd782360fef2a777391082.zip |
f2fs: fix to wait on page writeback in __clone_blkaddrs()
In below race condition, dst page may become writeback status
in __clone_blkaddrs(), it needs to wait writeback before update,
fix it.
Thread A GC Thread
- f2fs_move_file_range
- filemap_write_and_wait_range(dst)
- gc_data_segment
- f2fs_down_write(dst)
- move_data_page
- set_page_writeback(dst_page)
- f2fs_submit_page_write
- f2fs_up_write(dst)
- f2fs_down_write(dst)
- __exchange_data_block
- __clone_blkaddrs
- f2fs_get_new_data_page
- memcpy_page
Fixes: 0a2aa8fbb969 ("f2fs: refactor __exchange_data_block for speed up")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/file.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f4347db5b03e..719064730f9a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1325,6 +1325,9 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, f2fs_put_page(psrc, 1); return PTR_ERR(pdst); } + + f2fs_wait_on_page_writeback(pdst, DATA, true, true); + memcpy_page(pdst, 0, psrc, 0, PAGE_SIZE); set_page_dirty(pdst); set_page_private_gcing(pdst); |