Messages in this thread Patch in this message | | | From | Chao Yu <> | Subject | [PATCH] f2fs: fix to keep isolation of atomic write | Date | Fri, 25 Dec 2020 16:53:04 +0800 |
| |
ThreadA ThreadB - f2fs_ioc_start_atomic_write - write - f2fs_ioc_commit_atomic_write - f2fs_commit_inmem_pages - f2fs_drop_inmem_pages - f2fs_drop_inmem_pages - __revoke_inmem_pages - f2fs_vm_page_mkwrite - set_page_dirty - tag ATOMIC_WRITTEN_PAGE and add page to inmem_pages list - clear_inode_flag(FI_ATOMIC_FILE) - f2fs_vm_page_mkwrite - set_page_dirty - f2fs_update_dirty_page - f2fs_trace_pid - tag inmem page private to pid - truncate - f2fs_invalidate_page - set page->mapping to NULL then it will cause panic once we access page->mapping
The root cause is we missed to keep isolation of atomic write in the case of commit_atomic_write vs mkwrite, let commit_atomic_write helds i_mmap_sem lock to avoid this issue.
Signed-off-by: Chao Yu <yuchao0@huawei.com> --- fs/f2fs/file.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 22a0101538c0..1ff5fc10e1fa 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2094,10 +2094,12 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) goto err_out; } + down_write(&F2FS_I(inode)->i_mmap_sem); + if (f2fs_is_atomic_file(inode)) { ret = f2fs_commit_inmem_pages(inode); if (ret) - goto err_out; + goto up_write; ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true); if (!ret) @@ -2105,6 +2107,8 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) } else { ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false); } +up_write: + up_write(&F2FS_I(inode)->i_mmap_sem); err_out: if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) { clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST); -- 2.29.2
| |