• Dave Chinner's avatar
    xfs: remove xfs_fs_evict_inode() · 8179c036
    Dave Chinner authored
    Joe Lawrence reported a list_add corruption with 4.6-rc1 when
    testing some custom md administration code that made it's own
    block device nodes for the md array. The simple test loop of:
    
    for i in {0..100}; do
    	mknod --mode=0600 $tmp/tmp_node b $MAJOR $MINOR
    	mdadm --detail --export $tmp/tmp_node > /dev/null
    	rm -f $tmp/tmp_node
    done
    
    
    Would produce this warning in bd_acquire() when mdadm opened the
    device node:
    
    list_add double add: new=ffff88043831c7b8, prev=ffff8804380287d8, next=ffff88043831c7b8.
    
    And then produce this from bd_forget from kdevtmpfs evicting a block
    dev inode:
    
    list_del corruption. prev->next should be ffff8800bb83eb10, but was ffff88043831c7b8
    
    This is a regression caused by commit c19b3b05 ("xfs: mode di_mode
    to vfs inode"). The issue is that xfs_inactive() frees the
    unlinked inode, and the above commit meant that this freeing zeroed
    the mode in the struct inode. The problem is that after evict() has
    called ->evict_inode, it expects the i_mode to be intact so that it
    can call bd_forget() or cd_forget() to drop the reference to the
    block device inode attached to the XFS inode.
    
    In reality, the only thing we do in xfs_fs_evict_inode() that is not
    generic is call xfs_inactive(). We can move the xfs_inactive() call
    to xfs_fs_destroy_inode() without any problems at all, and this
    will leave the VFS inode intact until it is completely done with it.
    
    So, remove xfs_fs_evict_inode(), and do the work it used to do in
    ->destroy_inode instead.
    
    cc: <stable@vger.kernel.org> # 4.6
    Reported-by: default avatarJoe Lawrence <joe.lawrence@stratus.com>
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    8179c036
xfs_super.c 49.6 KB