• Miklos Szeredi's avatar
    vfs: dcache: fix deadlock in tree traversal · 8110e16d
    Miklos Szeredi authored
    IBM reported a deadlock in select_parent().  This was found to be caused
    by taking rename_lock when already locked when restarting the tree
    traversal.
    
    There are two cases when the traversal needs to be restarted:
    
     1) concurrent d_move(); this can only happen when not already locked,
        since taking rename_lock protects against concurrent d_move().
    
     2) racing with final d_put() on child just at the moment of ascending
        to parent; rename_lock doesn't protect against this rare race, so it
        can happen when already locked.
    
    Because of case 2, we need to be able to handle restarting the traversal
    when rename_lock is already held.  This patch fixes all three callers of
    try_to_ascend().
    
    IBM reported that the deadlock is gone with this patch.
    
    [ I rewrote the patch to be smaller and just do the "goto again" if the
      lock was already held, but credit goes to Miklos for the real work.
       - Linus ]
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
    Cc: Al Viro <viro@ZenIV.linux.org.uk>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    8110e16d
dcache.c 80.5 KB