| From aff5121b9fa34b4785ef1903ab2f969e7f32cbca Mon Sep 17 00:00:00 2001 |
| From: Jaegeuk Kim <jaegeuk@kernel.org> |
| Date: Tue, 3 Dec 2019 15:53:16 -0800 |
| Subject: [PATCH] f2fs: call f2fs_balance_fs outside of locked page |
| |
| commit bdf03299248916640a835a05d32841bb3d31912d upstream. |
| |
| Otherwise, we can hit deadlock by waiting for the locked page in |
| move_data_block in GC. |
| |
| Thread A Thread B |
| - do_page_mkwrite |
| - f2fs_vm_page_mkwrite |
| - lock_page |
| - f2fs_balance_fs |
| - mutex_lock(gc_mutex) |
| - f2fs_gc |
| - do_garbage_collect |
| - ra_data_block |
| - grab_cache_page |
| - f2fs_balance_fs |
| - mutex_lock(gc_mutex) |
| |
| Fixes: 39a8695824510 ("f2fs: refactor ->page_mkwrite() flow") |
| Reviewed-by: Chao Yu <yuchao0@huawei.com> |
| Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c |
| index 3d4ec1615bfa..bffdca9a10d6 100644 |
| --- a/fs/f2fs/file.c |
| +++ b/fs/f2fs/file.c |
| @@ -49,7 +49,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) |
| struct page *page = vmf->page; |
| struct inode *inode = file_inode(vmf->vma->vm_file); |
| struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
| - struct dnode_of_data dn = { .node_changed = false }; |
| + struct dnode_of_data dn; |
| int err; |
| |
| if (unlikely(f2fs_cp_error(sbi))) { |
| @@ -57,6 +57,9 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) |
| goto err; |
| } |
| |
| + /* should do out of any locked page */ |
| + f2fs_balance_fs(sbi, true); |
| + |
| sb_start_pagefault(inode->i_sb); |
| |
| f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); |
| @@ -114,8 +117,6 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) |
| out_sem: |
| up_read(&F2FS_I(inode)->i_mmap_sem); |
| |
| - f2fs_balance_fs(sbi, dn.node_changed); |
| - |
| sb_end_pagefault(inode->i_sb); |
| err: |
| return block_page_mkwrite_return(err); |
| -- |
| 2.7.4 |
| |