• Andreas Gruenbacher's avatar
    gfs2: gfs2_create_inode rework · 3d36e57f
    Andreas Gruenbacher authored
    When gfs2_lookup_by_inum() calls gfs2_inode_lookup() for an uncached
    inode, gfs2_inode_lookup() will place a new tentative inode into the
    inode cache before verifying that there is a valid inode at the given
    address.  This can race with gfs2_create_inode() which doesn't check for
    duplicates inodes.  gfs2_create_inode() will try to assign the new inode
    to the corresponding inode glock, and glock_set_object() will complain
    that the glock is still in use by gfs2_inode_lookup's tentative inode.
    
    We noticed this bug after adding commit 486408d6 ("gfs2: Cancel
    remote delete work asynchronously") which allowed delete_work_func() to
    race with gfs2_create_inode(), but the same race exists for
    open-by-handle.
    
    Fix that by switching from insert_inode_hash() to
    insert_inode_locked4(), which does check for duplicate inodes.  We know
    we've just managed to to allocate the new inode, so an inode tentatively
    created by gfs2_inode_lookup() will eventually go away and
    insert_inode_locked4() will always succeed.
    
    In addition, don't flush the inode glock work anymore (this can now only
    make things worse) and clean up glock_{set,clear}_object for the inode
    glock somewhat.
    Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
    3d36e57f
inode.c 51.5 KB