f2fs: fix to keep isolation of atomic write
As Yi Chen reported, there is a potential race case described as below:
Thread A Thread B
- f2fs_ioc_start_atomic_write
- mkwrite
- set_page_dirty
- f2fs_set_page_private(page, 0)
- set_inode_flag(FI_ATOMIC_FILE)
- mkwrite same page
- set_page_dirty
- f2fs_register_inmem_page
- f2fs_set_page_private(ATOMIC_WRITTEN_PAGE)
failed due to PagePrivate flag has been set
- list_add_tail
- truncate_inode_pages
- f2fs_invalidate_page
- clear page private but w/o remove it from
inmem_list
- set page->mapping to NULL
- f2fs_ioc_commit_atomic_write
- __f2fs_commit_inmem_pages
- __revoke_inmem_pages
- f2fs_put_page panic as page->mapping is NULL
The root cause is we missed to keep isolation of atomic write in the case
of start_atomic_write vs mkwrite, let start_atomic_write helds i_mmap_sem
lock to avoid this issue.
Reported-by: Yi Chen <chenyi77@huawei.com>
Signed-off-by: Chao Yu <chao@kernel.org>
2 files changed