• Benjamin Coddington's avatar
    mnt: fix __detach_mounts infinite loop · 1e9c75fb
    Benjamin Coddington authored
    Since commit ff17fa56 ("d_invalidate(): unhash immediately")
    immediately unhashes the dentry, we'll never return the mountpoint in
    lookup_mountpoint(), which can lead to an unbreakable loop in
    d_invalidate().
    
    I have reports of NFS clients getting into this condition after the server
    removes an export of an existing mount created through follow_automount(),
    but I suspect there are various other ways to produce this problem if we
    hunt down users of d_invalidate().  For example, it is possible to get into
    this state by using XFS' d_invalidate() call in xfs_vn_unlink():
    
    truncate -s 100m img{1,2}
    
    mkfs.xfs -q -n version=ci img1
    mkfs.xfs -q -n version=ci img2
    
    mkdir -p /mnt/xfs
    mount img1 /mnt/xfs
    
    mkdir /mnt/xfs/sub1
    mount img2 /mnt/xfs/sub1
    
    cat > /mnt/xfs/sub1/foo &
    umount -l /mnt/xfs/sub1
    mount img2 /mnt/xfs/sub1
    
    mount --make-private /mnt/xfs
    
    mkdir /mnt/xfs/sub2
    mount --move /mnt/xfs/sub1 /mnt/xfs/sub2
    rmdir /mnt/xfs/sub1
    
    Fix this by moving the check for an unlinked dentry out of the
    detach_mounts() path.
    
    Fixes: ff17fa56
    
     ("d_invalidate(): unhash immediately")
    Cc: stable@vger.kernel.org
    Reviewed-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
    Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
    Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
    1e9c75fb