• Jaegeuk Kim's avatar
    f2fs: fix to truncate dentry pages in the error case · bd859c65
    Jaegeuk Kim authored
    When a new directory is allocated, if an error is occurred, we should truncate
    preallocated dentry pages too.
    
    This bug was reported by Andrey Tsyvarev after a while as follows.
    
    mkdir()->
     f2fs_add_link()->
      init_inode_metadata()->
        f2fs_init_acl()->
          f2fs_get_acl()->
            f2fs_getxattr()->
              read_all_xattrs() fails.
    
    Also there was a BUG_ON triggered after the fault in
    mkdir()->
     f2fs_add_link()->
       init_inode_metadata()->
        remove_inode_page() ->
          f2fs_bug_on(inode->i_blocks != 0 && inode->i_blocks != 1);
    
    But, previous patch wasn't perfect to resolve that bug, so the following bug
    report was also submitted.
    
    kernel BUG at fs/f2fs/inode.c:274!
    Call Trace:
     [<ffffffff811fde03>] evict+0xa3/0x1a0
     [<ffffffff811fe615>] iput+0xf5/0x180
     [<ffffffffa01c7f63>] f2fs_mkdir+0xf3/0x150 [f2fs]
     [<ffffffff811f2a77>] vfs_mkdir+0xb7/0x160
     [<ffffffff811f36bf>] SyS_mkdir+0x5f/0xc0
     [<ffffffff81680769>] system_call_fastpath+0x16/0x1b
    
    Finally, this patch resolves all the issues like below.
    
    If an error is occurred after make_empty_dir(),
     1. truncate_inode_pages()
       The make_bad_inode() prior to iput() will change i_mode to S_IFREG, which
       means that f2fs will not decrement fi->dirty_dents during f2fs_evict_inode.
       But, by calling it here, we can do that.
    
     2. truncate_blocks()
       Preallocated dentry pages are trucated here to sync i_blocks.
    
     3. remove_dirty_dir_inode()
       Remove this directory inode from the list.
    Reported-and-Tested-by: default avatarAndrey Tsyvarev <tsyvarev@ispras.ru>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
    bd859c65
dir.c 16.6 KB