• Alexander Viro's avatar
    [PATCH] fix for nfs_unlink and vfs_unlink · 17191a2c
    Alexander Viro authored
    Ugh.  nfs_unlink() is actually racy as hell - look what happens if
    we enter it with ->d_count == 1, see that nfs_sillyrename() doesn't
    need to do anything and call nfs_safe_remove().  In the meanwhile
    somebody does dcache lookup (without going into NFS code - plain
    and simple cache hit) and increments ->d_count.  nfs_safe_remove()
    decides that something is very rotten and fails.
    
    AFAICS we should take the test for ->d_count + d_drop if it's 1
    under dcache_lock (and in one place).  Comments?
    
    Proposed fix follows:
    	* dget/dput killed in vfs_unlink() (safely)
    	* nfs_unlink() starts with check for ->d_count (under dcache_lock)
    	* if it's > 1 - sillyrename
    	* if it is 1 - immediately unhash, then drop dcache_lock.
    		after that we do as in old variant, except that
    		rehashing is done in nfs_unlink() and only if there
    		was an error - if there was none we simply leave
    		d_delete() to vfs_unlink().
    17191a2c
namei.c 50.8 KB