svn commit: r185557 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Tue Dec 2 03:14:17 PST 2008


Author: kib
Date: Tue Dec  2 11:14:16 2008
New Revision: 185557
URL: http://svn.freebsd.org/changeset/base/185557

Log:
  Shared lookup makes it possible to create several negative cache
  entries for one name. Then, creating inode with that name would remove
  one entry, leaving others dormant. Reclaiming the vnode would uncover
  negative entries, causing false return of ENOENT from the calls like
  stat, that do not create inode.
  
  Prevent creation of the duplicated negative entries.
  
  Reported and debugged with:	pho
  Reviewed by:	jhb
  X-MFC:	after shared lookup changes

Modified:
  head/sys/kern/vfs_cache.c

Modified: head/sys/kern/vfs_cache.c
==============================================================================
--- head/sys/kern/vfs_cache.c	Tue Dec  2 11:12:50 2008	(r185556)
+++ head/sys/kern/vfs_cache.c	Tue Dec  2 11:14:16 2008	(r185557)
@@ -474,7 +474,7 @@ cache_enter(dvp, vp, cnp)
 	struct vnode *vp;
 	struct componentname *cnp;
 {
-	struct namecache *ncp;
+	struct namecache *ncp, *n2;
 	struct nchashhead *ncpp;
 	u_int32_t hash;
 	int hold;
@@ -530,8 +530,6 @@ cache_enter(dvp, vp, cnp)
 	 * name.
 	 */
 	if (vp) {
-		struct namecache *n2;
-
 		TAILQ_FOREACH(n2, &vp->v_cache_dst, nc_dst) {
 			if (n2->nc_dvp == dvp &&
 			    n2->nc_nlen == cnp->cn_namelen &&
@@ -541,7 +539,16 @@ cache_enter(dvp, vp, cnp)
 				return;
 			}
 		}
-	}	
+	} else {
+		TAILQ_FOREACH(n2, &ncneg, nc_dst) {
+			if (n2->nc_nlen == cnp->cn_namelen &&
+			    !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) {
+				CACHE_UNLOCK();
+				cache_free(ncp);
+				return;
+			}
+		}
+	}
 
 	numcache++;
 	if (!vp) {


More information about the svn-src-head mailing list