Soft IRQ                                Thread
- f2fs_write_end_io
                                        - f2fs_defragment_range
                                         - set_page_private_gcing
 - type = WB_DATA_TYPE(page, false);
 : assign type w/ F2FS_WB_CP_DATA
 due to page_private_gcing() is true
  - dec_page_count() w/ wrong type
  - end_page_writeback()

Value of F2FS_WB_CP_DATA reference count may become negative under above
race condition, the root cause is we missed to wait page writeback before
setting gcing page private flag, let's fix it.

Fixes: 2d1fe8a86bf5 ("f2fs: fix to tag gcing flag on page during file 
defragment")
Fixes: 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block 
migration")
Signed-off-by: Chao Yu <c...@kernel.org>
---
 fs/f2fs/file.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index eaa39c50f782..56e27e305600 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2817,6 +2817,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
                                goto clear_out;
                        }
 
+                       f2fs_wait_on_page_writeback(page, DATA, true, true);
+
                        set_page_dirty(page);
                        set_page_private_gcing(page);
                        f2fs_put_page(page, 1);
@@ -4217,6 +4219,8 @@ static int redirty_blocks(struct inode *inode, pgoff_t 
page_idx, int len)
                /* It will never fail, when page has pinned above */
                f2fs_bug_on(F2FS_I_SB(inode), !page);
 
+               f2fs_wait_on_page_writeback(page, DATA, true, true);
+
                set_page_dirty(page);
                set_page_private_gcing(page);
                f2fs_put_page(page, 1);
-- 
2.40.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to