Skip to content
  • Jaegeuk Kim's avatar
    f2fs: fix BUG_ON during f2fs_evict_inode(dir) · 74d0b917
    Jaegeuk Kim authored
    
    
    During the dentry recovery routine, recover_inode() triggers __f2fs_add_link
    with its directory inode.
    
    In the following scenario, a bug is captured.
     1. dir = f2fs_iget(pino)
     2. __f2fs_add_link(dir, name)
     3. iput(dir)
      -> f2fs_evict_inode() faces with BUG_ON(atomic_read(fi->dirty_dents))
    
    Kernel BUG at ffffffffa01c0676 [verbose debug info unavailable]
    [<ffffffffa01c0676>] f2fs_evict_inode+0x276/0x300 [f2fs]
    Call Trace:
     [<ffffffff8118ea00>] evict+0xb0/0x1b0
     [<ffffffff8118f1c5>] iput+0x105/0x190
     [<ffffffffa01d2dac>] recover_fsync_data+0x3bc/0x1070 [f2fs]
     [<ffffffff81692e8a>] ? io_schedule+0xaa/0xd0
     [<ffffffff81690acb>] ? __wait_on_bit_lock+0x7b/0xc0
     [<ffffffff8111a0e7>] ? __lock_page+0x67/0x70
     [<ffffffff81165e21>] ? kmem_cache_alloc+0x31/0x140
     [<ffffffff8118a502>] ? __d_instantiate+0x92/0xf0
     [<ffffffff812a949b>] ? security_d_instantiate+0x1b/0x30
     [<ffffffff8118a5b4>] ? d_instantiate+0x54/0x70
    
    This means that we should flush all the dentry pages between iget and iput().
    But, during the recovery routine, it is unallowed due to consistency, so we
    have to wait the whole recovery process.
    And then, write_checkpoint flushes all the dirty dentry blocks, and nicely we
    can put the stale dir inodes from the dirty_dir_inode_list.
    
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
    74d0b917