• Andreas Gruenbacher's avatar
    gfs2: Fix gfs2_lookup_by_inum lock inversion · 3ce37b2c
    Andreas Gruenbacher authored
    The current gfs2_lookup_by_inum takes the glock of a presumed inode
    identified by block number, verifies that the block is indeed an inode,
    and then instantiates and reads the new inode via gfs2_inode_lookup.
    
    However, instantiating a new inode may block on freeing a previous
    instance of that inode (__wait_on_freeing_inode), and freeing an inode
    requires to take the glock already held, leading to lock inversion and
    deadlock.
    
    Fix this by first instantiating the new inode, then verifying that the
    block is an inode (if required), and then reading in the new inode, all
    in gfs2_inode_lookup.
    
    If the block we are looking for is not an inode, we discard the new
    inode via iget_failed, which marks inodes as bad and unhashes them.
    Other tasks waiting on that inode will get back a bad inode back from
    ilookup or iget_locked; in that case, retry the lookup.
    Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
    Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
    3ce37b2c
glock.c 51.2 KB