• Chao Yu's avatar
    f2fs: fix to writeout dirty inode during node flush · 052a82d8
    Chao Yu authored
    As Eric reported:
    
    On xfstest generic/204 on f2fs, I'm getting a kernel BUG.
    
     allocate_segment_by_default+0x9d/0x100 [f2fs]
     f2fs_allocate_data_block+0x3c0/0x5c0 [f2fs]
     do_write_page+0x62/0x110 [f2fs]
     f2fs_do_write_node_page+0x2b/0xa0 [f2fs]
     __write_node_page+0x2ec/0x590 [f2fs]
     f2fs_sync_node_pages+0x756/0x7e0 [f2fs]
     block_operations+0x25b/0x350 [f2fs]
     f2fs_write_checkpoint+0x104/0x1150 [f2fs]
     f2fs_sync_fs+0xa2/0x120 [f2fs]
     f2fs_balance_fs_bg+0x33c/0x390 [f2fs]
     f2fs_write_node_pages+0x4c/0x1f0 [f2fs]
     do_writepages+0x1c/0x70
     __writeback_single_inode+0x45/0x320
     writeback_sb_inodes+0x273/0x5c0
     wb_writeback+0xff/0x2e0
     wb_workfn+0xa1/0x370
     process_one_work+0x138/0x350
     worker_thread+0x4d/0x3d0
     kthread+0x109/0x140
    
    The root cause of this issue is, in a very small partition, e.g.
    in generic/204 testcase of fstest suit, filesystem's free space
    is 50MB, so at most we can write 12800 inline inode with command:
    `echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX > $SCRATCH_MNT/$i`,
    then filesystem will have:
    - 12800 dirty inline data page
    - 12800 dirty inode page
    - and 12800 dirty imeta (dirty inode)
    
    When we flush node-inode's page cache, we can also flush inline
    data with each inode page, however it will run out-of-free-space
    in device, then once it triggers checkpoint, there is no room for
    huge number of imeta, at this time, GC is useless, as there is no
    dirty segment at all.
    
    In order to fix this, we try to recognize inode page during
    node_inode's page flushing, and update inode page from dirty inode,
    so that later another imeta (dirty inode) flush can be avoided.
    Reported-and-tested-by: default avatarEric Biggers <ebiggers@kernel.org>
    Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    052a82d8
node.c 76.2 KB