Module Name: src Committed By: dholland Date: Mon Nov 5 17:24:12 UTC 2012
Modified Files: src/sys/fs/adosfs: adlookup.c src/sys/fs/cd9660: cd9660_lookup.c src/sys/fs/efs: efs_vnops.c src/sys/fs/filecorefs: filecore_lookup.c src/sys/fs/msdosfs: msdosfs_lookup.c src/sys/fs/nilfs: nilfs_vnops.c src/sys/fs/ntfs: ntfs_vnops.c src/sys/fs/puffs: puffs_vnops.c src/sys/fs/smbfs: smbfs_vnops.c src/sys/fs/tmpfs: tmpfs_vnops.c src/sys/fs/udf: udf_vnops.c src/sys/fs/union: union.h union_subr.c src/sys/kern: vfs_cache.c vfs_getcwd.c vfs_lookup.c src/sys/nfs: nfs_vnops.c src/sys/rump/librump/rumpvfs: rump_vfs.c src/sys/sys: namei.src src/sys/ufs/chfs: chfs_vnops.c src/sys/ufs/ext2fs: ext2fs_lookup.c src/sys/ufs/ufs: ufs_lookup.c Log Message: Disentangle the namecache from the internals of namei. - Move the namecache's hash computation to inside the namecache code, instead of being spread out all over the place. Remove cn_hash from struct componentname and delete all uses of it. - It is no longer necessary (if it ever was) for cache_lookup and cache_lookup_raw to clear MAKEENTRY from cnp->cn_flags for the cases that cache_enter already checks for. - Rearrange the interface of cache_lookup (and cache_lookup_raw) to make it somewhat simpler, to exclude certain nonexistent error conditions, and (most importantly) to make it not require write access to cnp->cn_flags. This change requires a kernel bump. To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/sys/fs/adosfs/adlookup.c cvs rdiff -u -r1.20 -r1.21 src/sys/fs/cd9660/cd9660_lookup.c cvs rdiff -u -r1.26 -r1.27 src/sys/fs/efs/efs_vnops.c cvs rdiff -u -r1.14 -r1.15 src/sys/fs/filecorefs/filecore_lookup.c cvs rdiff -u -r1.24 -r1.25 src/sys/fs/msdosfs/msdosfs_lookup.c cvs rdiff -u -r1.18 -r1.19 src/sys/fs/nilfs/nilfs_vnops.c cvs rdiff -u -r1.52 -r1.53 src/sys/fs/ntfs/ntfs_vnops.c cvs rdiff -u -r1.174 -r1.175 src/sys/fs/puffs/puffs_vnops.c cvs rdiff -u -r1.80 -r1.81 src/sys/fs/smbfs/smbfs_vnops.c cvs rdiff -u -r1.98 -r1.99 src/sys/fs/tmpfs/tmpfs_vnops.c cvs rdiff -u -r1.72 -r1.73 src/sys/fs/udf/udf_vnops.c cvs rdiff -u -r1.23 -r1.24 src/sys/fs/union/union.h cvs rdiff -u -r1.55 -r1.56 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.89 -r1.90 src/sys/kern/vfs_cache.c cvs rdiff -u -r1.47 -r1.48 src/sys/kern/vfs_getcwd.c cvs rdiff -u -r1.196 -r1.197 src/sys/kern/vfs_lookup.c cvs rdiff -u -r1.295 -r1.296 src/sys/nfs/nfs_vnops.c cvs rdiff -u -r1.67 -r1.68 src/sys/rump/librump/rumpvfs/rump_vfs.c cvs rdiff -u -r1.27 -r1.28 src/sys/sys/namei.src cvs rdiff -u -r1.11 -r1.12 src/sys/ufs/chfs/chfs_vnops.c cvs rdiff -u -r1.70 -r1.71 src/sys/ufs/ext2fs/ext2fs_lookup.c cvs rdiff -u -r1.118 -r1.119 src/sys/ufs/ufs/ufs_lookup.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/adosfs/adlookup.c diff -u src/sys/fs/adosfs/adlookup.c:1.16 src/sys/fs/adosfs/adlookup.c:1.17 --- src/sys/fs/adosfs/adlookup.c:1.16 Sun Jul 22 00:53:18 2012 +++ src/sys/fs/adosfs/adlookup.c Mon Nov 5 17:24:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: adlookup.c,v 1.16 2012/07/22 00:53:18 rmind Exp $ */ +/* $NetBSD: adlookup.c,v 1.17 2012/11/05 17:24:09 dholland Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: adlookup.c,v 1.16 2012/07/22 00:53:18 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: adlookup.c,v 1.17 2012/11/05 17:24:09 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -110,8 +110,9 @@ adosfs_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) - return (error); + if (cache_lookup(vdp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT : 0; + } /* * fake a '.' Index: src/sys/fs/cd9660/cd9660_lookup.c diff -u src/sys/fs/cd9660/cd9660_lookup.c:1.20 src/sys/fs/cd9660/cd9660_lookup.c:1.21 --- src/sys/fs/cd9660/cd9660_lookup.c:1.20 Sun Jul 22 00:53:18 2012 +++ src/sys/fs/cd9660/cd9660_lookup.c Mon Nov 5 17:24:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_lookup.c,v 1.20 2012/07/22 00:53:18 rmind Exp $ */ +/* $NetBSD: cd9660_lookup.c,v 1.21 2012/11/05 17:24:09 dholland Exp $ */ /*- * Copyright (c) 1989, 1993, 1994 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_lookup.c,v 1.20 2012/07/22 00:53:18 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_lookup.c,v 1.21 2012/11/05 17:24:09 dholland Exp $"); #include <sys/param.h> #include <sys/namei.h> @@ -151,8 +151,9 @@ cd9660_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) - return (error); + if (cache_lookup(vdp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT : 0; + } len = cnp->cn_namelen; name = cnp->cn_nameptr; Index: src/sys/fs/efs/efs_vnops.c diff -u src/sys/fs/efs/efs_vnops.c:1.26 src/sys/fs/efs/efs_vnops.c:1.27 --- src/sys/fs/efs/efs_vnops.c:1.26 Sun Jul 22 00:53:19 2012 +++ src/sys/fs/efs/efs_vnops.c Mon Nov 5 17:24:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: efs_vnops.c,v 1.26 2012/07/22 00:53:19 rmind Exp $ */ +/* $NetBSD: efs_vnops.c,v 1.27 2012/11/05 17:24:09 dholland Exp $ */ /* * Copyright (c) 2006 Stephen M. Rumble <rum...@ephemeral.org> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.26 2012/07/22 00:53:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.27 2012/11/05 17:24:09 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -73,9 +73,9 @@ efs_lookup(void *v) if (err) return (err); - err = cache_lookup(ap->a_dvp, ap->a_vpp, cnp); - if (err != -1) - return (err); + if (cache_lookup(ap->a_dvp, cnp, NULL, ap->a_vpp)) { + return *ap->a_vpp == NULLVP ? ENOENT : 0; + } /* * Handle the three lookup types: '.', '..', and everything else. Index: src/sys/fs/filecorefs/filecore_lookup.c diff -u src/sys/fs/filecorefs/filecore_lookup.c:1.14 src/sys/fs/filecorefs/filecore_lookup.c:1.15 --- src/sys/fs/filecorefs/filecore_lookup.c:1.14 Sun Jul 22 00:53:19 2012 +++ src/sys/fs/filecorefs/filecore_lookup.c Mon Nov 5 17:24:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: filecore_lookup.c,v 1.14 2012/07/22 00:53:19 rmind Exp $ */ +/* $NetBSD: filecore_lookup.c,v 1.15 2012/11/05 17:24:09 dholland Exp $ */ /*- * Copyright (c) 1989, 1993, 1994 The Regents of the University of California. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: filecore_lookup.c,v 1.14 2012/07/22 00:53:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: filecore_lookup.c,v 1.15 2012/11/05 17:24:09 dholland Exp $"); #include <sys/param.h> #include <sys/namei.h> @@ -169,8 +169,9 @@ filecore_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) - return (error); + if (cache_lookup(vdp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT : 0; + } name = cnp->cn_nameptr; namelen = cnp->cn_namelen; Index: src/sys/fs/msdosfs/msdosfs_lookup.c diff -u src/sys/fs/msdosfs/msdosfs_lookup.c:1.24 src/sys/fs/msdosfs/msdosfs_lookup.c:1.25 --- src/sys/fs/msdosfs/msdosfs_lookup.c:1.24 Sun Jul 22 00:53:19 2012 +++ src/sys/fs/msdosfs/msdosfs_lookup.c Mon Nov 5 17:24:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_lookup.c,v 1.24 2012/07/22 00:53:19 rmind Exp $ */ +/* $NetBSD: msdosfs_lookup.c,v 1.25 2012/11/05 17:24:10 dholland Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_lookup.c,v 1.24 2012/07/22 00:53:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_lookup.c,v 1.25 2012/11/05 17:24:10 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -146,8 +146,9 @@ msdosfs_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) - return (error); + if (cache_lookup(vdp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT: 0; + } /* * If they are going after the . or .. entry in the root directory, Index: src/sys/fs/nilfs/nilfs_vnops.c diff -u src/sys/fs/nilfs/nilfs_vnops.c:1.18 src/sys/fs/nilfs/nilfs_vnops.c:1.19 --- src/sys/fs/nilfs/nilfs_vnops.c:1.18 Sun Jul 22 00:53:19 2012 +++ src/sys/fs/nilfs/nilfs_vnops.c Mon Nov 5 17:24:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_vnops.c,v 1.18 2012/07/22 00:53:19 rmind Exp $ */ +/* $NetBSD: nilfs_vnops.c,v 1.19 2012/11/05 17:24:10 dholland Exp $ */ /* * Copyright (c) 2008, 2009 Reinoud Zandijk @@ -28,7 +28,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.18 2012/07/22 00:53:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.19 2012/11/05 17:24:10 dholland Exp $"); #endif /* not lint */ @@ -652,10 +652,10 @@ nilfs_lookup(void *v) DPRINTF(LOOKUP, ("\tlooking up cnp->cn_nameptr '%s'\n", cnp->cn_nameptr)); - /* look in the nami cache; returns 0 on success!! */ - error = cache_lookup(dvp, vpp, cnp); - if (error >= 0) - return error; + /* look in the namecache */ + if (cache_lookup(dvp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT : 0; + } DPRINTF(LOOKUP, ("\tNOT found in cache\n")); Index: src/sys/fs/ntfs/ntfs_vnops.c diff -u src/sys/fs/ntfs/ntfs_vnops.c:1.52 src/sys/fs/ntfs/ntfs_vnops.c:1.53 --- src/sys/fs/ntfs/ntfs_vnops.c:1.52 Sun Jul 22 00:53:19 2012 +++ src/sys/fs/ntfs/ntfs_vnops.c Mon Nov 5 17:24:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ntfs_vnops.c,v 1.52 2012/07/22 00:53:19 rmind Exp $ */ +/* $NetBSD: ntfs_vnops.c,v 1.53 2012/11/05 17:24:10 dholland Exp $ */ /* * Copyright (c) 1992, 1993 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.52 2012/07/22 00:53:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.53 2012/11/05 17:24:10 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -682,8 +682,9 @@ ntfs_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(ap->a_dvp, ap->a_vpp, cnp)) >= 0) - return (error); + if (cache_lookup(ap->a_dvp, cnp, NULL, ap->a_vpp)) { + return *ap->a_vpp == NULLVP ? ENOENT : 0; + } if(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { dprintf(("ntfs_lookup: faking . directory in %llu\n", Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.174 src/sys/fs/puffs/puffs_vnops.c:1.175 --- src/sys/fs/puffs/puffs_vnops.c:1.174 Fri Aug 10 16:49:35 2012 +++ src/sys/fs/puffs/puffs_vnops.c Mon Nov 5 17:24:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.174 2012/08/10 16:49:35 manu Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.175 2012/11/05 17:24:10 dholland Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.174 2012/08/10 16:49:35 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.175 2012/11/05 17:24:10 dholland Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -526,9 +526,14 @@ puffs_vnop_lookup(void *v) * Check if someone fed it into the cache */ if (!isdot && PUFFS_USE_NAMECACHE(pmp)) { - error = cache_lookup(dvp, ap->a_vpp, cnp); + int found, iswhiteout; - if ((error == 0) && PUFFS_USE_FS_TTL(pmp)) { + found = cache_lookup(dvp, cnp, &iswhiteout, ap->a_vpp); + if (iswhiteout) { + cnp->cn_flags |= ISWHITEOUT; + } + + if (found && *ap->a_vpp != NULLVP && PUFFS_USE_FS_TTL(pmp)) { cvp = *ap->a_vpp; cpn = VPTOPP(cvp); @@ -540,7 +545,7 @@ puffs_vnop_lookup(void *v) * successful lookup. */ *ap->a_vpp = NULL; - error = -1; + found = 0; } } @@ -548,11 +553,20 @@ puffs_vnop_lookup(void *v) * Do not use negative caching, since the filesystem * provides no TTL for it. */ - if ((error == ENOENT) && PUFFS_USE_FS_TTL(pmp)) - error = -1; + if (found && *ap->a_vpp == NULLVP && PUFFS_USE_FS_TTL(pmp)) + found = 0; - if (error >= 0) - return error; + if (found) { + return *ap->a_vpp == NULLVP ? ENOENT : 0; + } + + /* + * This is what would have been left in ERROR before + * the rearrangement of cache_lookup(). What with all + * the macros, I am not sure if this is a dead value + * below or not. + */ + error = -1; } if (isdot) { Index: src/sys/fs/smbfs/smbfs_vnops.c diff -u src/sys/fs/smbfs/smbfs_vnops.c:1.80 src/sys/fs/smbfs/smbfs_vnops.c:1.81 --- src/sys/fs/smbfs/smbfs_vnops.c:1.80 Sun Jul 22 00:53:20 2012 +++ src/sys/fs/smbfs/smbfs_vnops.c Mon Nov 5 17:24:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: smbfs_vnops.c,v 1.80 2012/07/22 00:53:20 rmind Exp $ */ +/* $NetBSD: smbfs_vnops.c,v 1.81 2012/11/05 17:24:10 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.80 2012/07/22 00:53:20 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.81 2012/11/05 17:24:10 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1202,29 +1202,23 @@ smbfs_lookup(void *v) * the time the cache entry has been created. If it has, * the cache entry has to be ignored. */ - if ((error = cache_lookup(dvp, vpp, cnp)) >= 0) { + if (cache_lookup(dvp, cnp, NULL, vpp)) { struct vattr vattr; struct vnode *newvp; - int err2; - if (error && error != ENOENT) { - *vpp = NULLVP; - return error; - } - - err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); - if (err2 != 0) { - if (error == 0) { + error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); + if (error != 0) { + if (*vpp != NULLVP) { if (*vpp != dvp) vput(*vpp); else vrele(*vpp); } *vpp = NULLVP; - return err2; + return error; } - if (error == ENOENT) { + if (*vpp == NULLVP) { if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred) && vattr.va_mtime.tv_sec == VTOSMB(dvp)->n_nctime) return ENOENT; Index: src/sys/fs/tmpfs/tmpfs_vnops.c diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.98 src/sys/fs/tmpfs/tmpfs_vnops.c:1.99 --- src/sys/fs/tmpfs/tmpfs_vnops.c:1.98 Sun Jul 22 00:53:21 2012 +++ src/sys/fs/tmpfs/tmpfs_vnops.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vnops.c,v 1.98 2012/07/22 00:53:21 rmind Exp $ */ +/* $NetBSD: tmpfs_vnops.c,v 1.99 2012/11/05 17:24:11 dholland Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.98 2012/07/22 00:53:21 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.99 2012/11/05 17:24:11 dholland Exp $"); #include <sys/param.h> #include <sys/dirent.h> @@ -133,6 +133,7 @@ tmpfs_lookup(void *v) const bool lastcn = (cnp->cn_flags & ISLASTCN) != 0; tmpfs_node_t *dnode, *tnode; tmpfs_dirent_t *de; + int cachefound, iswhiteout; int error; KASSERT(VOP_ISLOCKED(dvp)); @@ -160,9 +161,16 @@ tmpfs_lookup(void *v) * Avoid doing a linear scan of the directory if the requested * directory/name couple is already in the cache. */ - error = cache_lookup(dvp, vpp, cnp); - if (error >= 0) { - /* Both cache-hit or an error case. */ + cachefound = cache_lookup(dvp, cnp, &iswhiteout, vpp); + if (iswhiteout) { + cnp->cn_flags |= ISWHITEOUT; + } + if (cachefound && *vpp == NULLVP) { + /* Negative cache hit. */ + error = ENOENT; + goto out; + } else if (cachefound) { + error = 0; goto out; } Index: src/sys/fs/udf/udf_vnops.c diff -u src/sys/fs/udf/udf_vnops.c:1.72 src/sys/fs/udf/udf_vnops.c:1.73 --- src/sys/fs/udf/udf_vnops.c:1.72 Sun Jul 22 00:53:21 2012 +++ src/sys/fs/udf/udf_vnops.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.72 2012/07/22 00:53:21 rmind Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.73 2012/11/05 17:24:11 dholland Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.72 2012/07/22 00:53:21 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.73 2012/11/05 17:24:11 dholland Exp $"); #endif /* not lint */ @@ -687,10 +687,10 @@ udf_lookup(void *v) DPRINTF(LOOKUP, ("\tlooking up cnp->cn_nameptr '%s'\n", cnp->cn_nameptr)); - /* look in the nami cache; returns 0 on success!! */ - error = cache_lookup(dvp, vpp, cnp); - if (error >= 0) - return error; + /* look in the namecache */ + if (cache_lookup(dvp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT : 0; + } DPRINTF(LOOKUP, ("\tNOT found in cache\n")); Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.23 src/sys/fs/union/union.h:1.24 --- src/sys/fs/union/union.h:1.23 Wed Nov 23 19:39:11 2011 +++ src/sys/fs/union/union.h Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.23 2011/11/23 19:39:11 hannken Exp $ */ +/* $NetBSD: union.h,v 1.24 2012/11/05 17:24:11 dholland Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -126,7 +126,6 @@ struct union_node { struct vnode *un_dirvp; /* v: Parent dir of uppervp */ struct vnode *un_pvp; /* v: Parent vnode */ char *un_path; /* v: saved component name */ - int un_hash; /* v: saved un_path hash */ int un_openl; /* v: # of opens on lowervp */ unsigned int un_flags; /* v: node flags */ unsigned int un_cflags; /* c: cache flags */ Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.55 src/sys/fs/union/union_subr.c:1.56 --- src/sys/fs/union/union_subr.c:1.55 Fri Nov 25 11:19:10 2011 +++ src/sys/fs/union/union_subr.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.55 2011/11/25 11:19:10 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.56 2012/11/05 17:24:11 dholland Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.55 2011/11/25 11:19:10 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.56 2012/11/05 17:24:11 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -105,7 +105,7 @@ static u_long uhash_mask; /* size of ha static kmutex_t uhash_lock; void union_updatevp(struct union_node *, struct vnode *, struct vnode *); -static int union_do_lookup(struct vnode *, struct componentname *, kauth_cred_t, const char *, u_long); +static int union_do_lookup(struct vnode *, struct componentname *, kauth_cred_t, const char *); int union_vn_close(struct vnode *, int, kauth_cred_t, struct lwp *); static void union_dircache_r(struct vnode *, struct vnode ***, int *); struct vnode *union_dircache(struct vnode *, struct lwp *); @@ -451,7 +451,6 @@ found: if (lowervp != un->un_lowervp) { union_newlower(un, lowervp); if (cnp && (lowervp != NULLVP)) { - un->un_hash = cnp->cn_hash; un->un_path = malloc(cnp->cn_namelen+1, M_TEMP, M_WAITOK); memcpy(un->un_path, cnp->cn_nameptr, @@ -572,14 +571,12 @@ found: union_newsize(*vpp, uppersz, lowersz); if (dvp && cnp && (lowervp != NULLVP)) { - un->un_hash = cnp->cn_hash; un->un_path = malloc(cnp->cn_namelen+1, M_TEMP, M_WAITOK); memcpy(un->un_path, cnp->cn_nameptr, cnp->cn_namelen); un->un_path[cnp->cn_namelen] = '\0'; vref(dvp); un->un_dirvp = dvp; } else { - un->un_hash = 0; un->un_path = 0; un->un_dirvp = 0; } @@ -778,10 +775,9 @@ union_copyup(struct union_node *un, int */ static int union_do_lookup(struct vnode *dvp, struct componentname *cnp, kauth_cred_t cred, - const char *path, u_long hash) + const char *path) { int error; - const char *cp; struct vnode *vp; cnp->cn_nameiop = CREATE; @@ -789,13 +785,6 @@ union_do_lookup(struct vnode *dvp, struc cnp->cn_cred = cred; cnp->cn_nameptr = path; cnp->cn_namelen = strlen(path); - if (hash == 0) { - cp = NULL; - cnp->cn_hash = namei_hash(cnp->cn_nameptr, &cp); - KASSERT(*cp == 0); - } else { - cnp->cn_hash = hash; - } error = VOP_LOOKUP(dvp, &vp, cnp); @@ -847,7 +836,7 @@ union_mkshadow(struct union_mount *um, s vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); error = union_do_lookup(dvp, &cn, - (um->um_op == UNMNT_ABOVE ? cnp->cn_cred : um->um_cred), pnbuf, 0); + (um->um_op == UNMNT_ABOVE ? cnp->cn_cred : um->um_cred), pnbuf); if (error) { VOP_UNLOCK(dvp); PNBUF_PUT(pnbuf); @@ -891,7 +880,7 @@ union_mkwhiteout(struct union_mount *um, error = union_do_lookup(dvp, &cn, (um->um_op == UNMNT_ABOVE ? cnp->cn_cred : um->um_cred), - un->un_path, un->un_hash); + un->un_path); if (error) return error; @@ -924,7 +913,7 @@ union_vn_create(struct vnode **vpp, stru vn_lock(un->un_dirvp, LK_EXCLUSIVE | LK_RETRY); error = union_do_lookup(un->un_dirvp, &cn, l->l_cred, - un->un_path, un->un_hash); + un->un_path); if (error) { VOP_UNLOCK(un->un_dirvp); return error; @@ -1197,7 +1186,6 @@ union_check_rmdir(struct union_node *un, cn.cn_cred = cred; cn.cn_nameptr = dp->d_name; cn.cn_namelen = dp->d_namlen; - cn.cn_hash = 0; error = VOP_LOOKUP(un->un_uppervp, &tvp, &cn); if (error == ENOENT && (cn.cn_flags & ISWHITEOUT)) { error = 0; Index: src/sys/kern/vfs_cache.c diff -u src/sys/kern/vfs_cache.c:1.89 src/sys/kern/vfs_cache.c:1.90 --- src/sys/kern/vfs_cache.c:1.89 Sun Jul 22 00:53:18 2012 +++ src/sys/kern/vfs_cache.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_cache.c,v 1.89 2012/07/22 00:53:18 rmind Exp $ */ +/* $NetBSD: vfs_cache.c,v 1.90 2012/11/05 17:24:11 dholland Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.89 2012/07/22 00:53:18 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.90 2012/11/05 17:24:11 dholland Exp $"); #include "opt_ddb.h" #include "opt_revcache.h" @@ -109,6 +109,16 @@ struct nchcpu { }; /* + * The type for the hash code. While the hash function generates a + * u32, the hash code has historically been passed around as a u_long, + * and the value is modified by xor'ing a uintptr_t, so it's not + * entirely clear what the best type is. For now I'll leave it + * unchanged as u_long. + */ + +typedef u_long nchash_t; + +/* * Structures associated with name cacheing. */ @@ -119,8 +129,8 @@ static TAILQ_HEAD(, namecache) nclruhead static LIST_HEAD(nchashhead, namecache) *nchashtbl __read_mostly; static u_long nchash __read_mostly; -#define NCHASH(cnp, dvp) \ - (((cnp)->cn_hash ^ ((uintptr_t)(dvp) >> 3)) & nchash) +#define NCHASH2(hash, dvp) \ + (((hash) ^ ((uintptr_t)(dvp) >> 3)) & nchash) static LIST_HEAD(ncvhashhead, namecache) *ncvhashtbl __read_mostly; static u_long ncvhash __read_mostly; @@ -160,6 +170,21 @@ static int cache_ctor(void *, void *, in static void cache_dtor(void *, void *); /* + * Compute the hash for an entry. + * + * (This is for now a wrapper around namei_hash, whose interface is + * for the time being slightly inconvenient.) + */ +static nchash_t +cache_hash(const struct componentname *cnp) +{ + const char *endptr; + + endptr = cnp->cn_nameptr + cnp->cn_namelen; + return namei_hash(cnp->cn_nameptr, &endptr); +} + +/* * Invalidate a cache entry and enqueue it for garbage collection. */ static void @@ -261,9 +286,11 @@ cache_lookup_entry(const struct vnode *d { struct nchashhead *ncpp; struct namecache *ncp; + nchash_t hash; KASSERT(dvp != NULL); - ncpp = &nchashtbl[NCHASH(cnp, dvp)]; + hash = cache_hash(cnp); + ncpp = &nchashtbl[NCHASH2(hash, dvp)]; LIST_FOREACH(ncp, ncpp, nc_hash) { if (ncp->nc_dvp != dvp || @@ -288,45 +315,83 @@ cache_lookup_entry(const struct vnode *d * holding long names (which would either waste space, or * add greatly to the complexity). * - * Lookup is called with ni_dvp pointing to the directory to search, - * ni_ptr pointing to the name of the entry being sought, ni_namelen - * tells the length of the name, and ni_hash contains a hash of - * the name. If the lookup succeeds, the vnode is locked, stored in ni_vp - * and a status of zero is returned. If the locking fails for whatever - * reason, the vnode is unlocked and the error is returned to caller. - * If the lookup determines that the name does not exist (negative cacheing), - * a status of ENOENT is returned. If the lookup fails, a status of -1 - * is returned. + * Lookup is called with DVP pointing to the directory to search, + * and CNP providing the name of the entry being sought: cn_nameptr + * is the name, cn_namelen is its length, and cn_flags is the flags + * word from the namei operation. + * + * DVP must be locked. + * + * There are three possible non-error return states: + * 1. Nothing was found in the cache. Nothing is known about + * the requested name. + * 2. A negative entry was found in the cache, meaning that the + * requested name definitely does not exist. + * 3. A positive entry was found in the cache, meaning that the + * requested name does exist and that we are providing the + * vnode. + * In these cases the results are: + * 1. 0 returned; VN is set to NULL. + * 2. 1 returned; VN is set to NULL. + * 3. 1 returned; VN is set to the vnode found. + * + * The additional result argument ISWHT is set to zero, unless a + * negative entry is found that was entered as a whiteout, in which + * case ISWHT is set to one. + * + * The ISWHT_RET argument pointer may be null. In this case an + * assertion is made that the whiteout flag is not set. File systems + * that do not support whiteouts can/should do this. + * + * Filesystems that do support whiteouts should add ISWHITEOUT to + * cnp->cn_flags if ISWHT comes back nonzero. + * + * When a vnode is returned, it is locked, as per the vnode lookup + * locking protocol. + * + * There is no way for this function to fail, in the sense of + * generating an error that requires aborting the namei operation. + * + * (Prior to October 2012, this function returned an integer status, + * and a vnode, and mucked with the flags word in CNP for whiteouts. + * The integer status was -1 for "nothing found", ENOENT for "a + * negative entry found", 0 for "a positive entry found", and possibly + * other errors, and the value of VN might or might not have been set + * depending on what error occurred.) */ int -cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) +cache_lookup(struct vnode *dvp, const struct componentname *cnp, + int *iswht_ret, struct vnode **vn_ret) { struct namecache *ncp; struct vnode *vp; struct nchcpu *cpup; int error; + /* Establish default result values */ + if (iswht_ret != NULL) { + *iswht_ret = 0; + } + *vn_ret = NULL; + if (__predict_false(!doingcache)) { - cnp->cn_flags &= ~MAKEENTRY; - *vpp = NULL; - return -1; + return 0; } cpup = curcpu()->ci_data.cpu_nch; mutex_enter(&cpup->cpu_lock); if (__predict_false(cnp->cn_namelen > NCHNAMLEN)) { COUNT(cpup->cpu_stats, ncs_long); - cnp->cn_flags &= ~MAKEENTRY; mutex_exit(&cpup->cpu_lock); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } ncp = cache_lookup_entry(dvp, cnp); if (__predict_false(ncp == NULL)) { COUNT(cpup->cpu_stats, ncs_miss); mutex_exit(&cpup->cpu_lock); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } if ((cnp->cn_flags & MAKEENTRY) == 0) { COUNT(cpup->cpu_stats, ncs_badhits); @@ -338,20 +403,28 @@ cache_lookup(struct vnode *dvp, struct v cache_invalidate(ncp); mutex_exit(&ncp->nc_lock); mutex_exit(&cpup->cpu_lock); - *vpp = NULL; - return -1; - } else if (ncp->nc_vp == NULL) { - /* - * Restore the ISWHITEOUT flag saved earlier. - */ - KASSERT((ncp->nc_flags & ~ISWHITEOUT) == 0); - cnp->cn_flags |= ncp->nc_flags; + /* found nothing */ + return 0; + } + if (ncp->nc_vp == NULL) { + if (iswht_ret != NULL) { + /* + * Restore the ISWHITEOUT flag saved earlier. + */ + KASSERT((ncp->nc_flags & ~ISWHITEOUT) == 0); + /*cnp->cn_flags |= ncp->nc_flags;*/ + *iswht_ret = (ncp->nc_flags & ISWHITEOUT) != 0; + } else { + KASSERT(ncp->nc_flags == 0); + } + if (__predict_true(cnp->cn_nameiop != CREATE || (cnp->cn_flags & ISLASTCN) == 0)) { COUNT(cpup->cpu_stats, ncs_neghits); mutex_exit(&ncp->nc_lock); mutex_exit(&cpup->cpu_lock); - return ENOENT; + /* found neg entry; vn is already null from above */ + return 1; } else { COUNT(cpup->cpu_stats, ncs_badhits); /* @@ -363,8 +436,8 @@ cache_lookup(struct vnode *dvp, struct v cache_invalidate(ncp); mutex_exit(&ncp->nc_lock); mutex_exit(&cpup->cpu_lock); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } } @@ -384,8 +457,8 @@ cache_lookup(struct vnode *dvp, struct v * XXX badhits? */ COUNT(cpup->cpu_stats, ncs_falsehits); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } } @@ -411,61 +484,72 @@ cache_lookup(struct vnode *dvp, struct v * Check that the lock succeeded. */ if (error) { - /* Unlocked, but only for stats. */ + /* We don't have the right lock, but this is only for stats. */ COUNT(cpup->cpu_stats, ncs_badhits); + vrele(vp); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } - /* Unlocked, but only for stats. */ + /* We don't have the right lock, but this is only for stats. */ COUNT(cpup->cpu_stats, ncs_goodhits); - *vpp = vp; - return 0; + + /* found it */ + *vn_ret = vp; + return 1; } int -cache_lookup_raw(struct vnode *dvp, struct vnode **vpp, - struct componentname *cnp) +cache_lookup_raw(struct vnode *dvp, const struct componentname *cnp, + int *iswht_ret, struct vnode **vn_ret) { struct namecache *ncp; struct vnode *vp; struct nchcpu *cpup; int error; + /* Establish default results. */ + if (iswht_ret != NULL) { + *iswht_ret = 0; + } + *vn_ret = NULL; + if (__predict_false(!doingcache)) { - cnp->cn_flags &= ~MAKEENTRY; - *vpp = NULL; - return (-1); + /* found nothing */ + return 0; } cpup = curcpu()->ci_data.cpu_nch; mutex_enter(&cpup->cpu_lock); if (__predict_false(cnp->cn_namelen > NCHNAMLEN)) { COUNT(cpup->cpu_stats, ncs_long); - cnp->cn_flags &= ~MAKEENTRY; mutex_exit(&cpup->cpu_lock); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } ncp = cache_lookup_entry(dvp, cnp); if (__predict_false(ncp == NULL)) { COUNT(cpup->cpu_stats, ncs_miss); mutex_exit(&cpup->cpu_lock); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } vp = ncp->nc_vp; if (vp == NULL) { /* * Restore the ISWHITEOUT flag saved earlier. */ - KASSERT((ncp->nc_flags & ~ISWHITEOUT) == 0); - cnp->cn_flags |= ncp->nc_flags; + if (iswht_ret != NULL) { + KASSERT((ncp->nc_flags & ~ISWHITEOUT) == 0); + /*cnp->cn_flags |= ncp->nc_flags;*/ + *iswht_ret = (ncp->nc_flags & ISWHITEOUT) != 0; + } COUNT(cpup->cpu_stats, ncs_neghits); mutex_exit(&ncp->nc_lock); mutex_exit(&cpup->cpu_lock); - return ENOENT; + /* found negative entry; vn is already null from above */ + return 1; } if (vtryget(vp)) { mutex_exit(&ncp->nc_lock); @@ -482,15 +566,17 @@ cache_lookup_raw(struct vnode *dvp, stru * XXX badhits? */ COUNT(cpup->cpu_stats, ncs_falsehits); - *vpp = NULL; - return -1; + /* found nothing */ + return 0; } } /* Unlocked, but only for stats. */ COUNT(cpup->cpu_stats, ncs_goodhits); /* XXX can be "badhits" */ - *vpp = vp; - return 0; + + /* found it */ + *vn_ret = vp; + return 1; } /* @@ -590,6 +676,7 @@ cache_enter(struct vnode *dvp, struct vn struct namecache *oncp; struct nchashhead *ncpp; struct ncvhashhead *nvcpp; + nchash_t hash; /* First, check whether we can/should add a cache entry. */ if ((cnp->cn_flags & MAKEENTRY) == 0 || @@ -645,7 +732,8 @@ cache_enter(struct vnode *dvp, struct vn ncp->nc_nlen = cnp->cn_namelen; memcpy(ncp->nc_name, cnp->cn_nameptr, (unsigned)ncp->nc_nlen); TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); - ncpp = &nchashtbl[NCHASH(cnp, dvp)]; + hash = cache_hash(cnp); + ncpp = &nchashtbl[NCHASH2(hash, dvp)]; /* * Flush updates before making visible in table. No need for a Index: src/sys/kern/vfs_getcwd.c diff -u src/sys/kern/vfs_getcwd.c:1.47 src/sys/kern/vfs_getcwd.c:1.48 --- src/sys/kern/vfs_getcwd.c:1.47 Tue Nov 30 10:30:02 2010 +++ src/sys/kern/vfs_getcwd.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_getcwd.c,v 1.47 2010/11/30 10:30:02 dholland Exp $ */ +/* $NetBSD: vfs_getcwd.c,v 1.48 2012/11/05 17:24:11 dholland Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_getcwd.c,v 1.47 2010/11/30 10:30:02 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_getcwd.c,v 1.48 2012/11/05 17:24:11 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -130,7 +130,6 @@ getcwd_scandir(struct vnode **lvpp, stru cn.cn_cred = cred; cn.cn_nameptr = ".."; cn.cn_namelen = 2; - cn.cn_hash = 0; cn.cn_consume = 0; /* Index: src/sys/kern/vfs_lookup.c diff -u src/sys/kern/vfs_lookup.c:1.196 src/sys/kern/vfs_lookup.c:1.197 --- src/sys/kern/vfs_lookup.c:1.196 Sat Oct 13 17:46:50 2012 +++ src/sys/kern/vfs_lookup.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lookup.c,v 1.196 2012/10/13 17:46:50 dholland Exp $ */ +/* $NetBSD: vfs_lookup.c,v 1.197 2012/11/05 17:24:11 dholland Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.196 2012/10/13 17:46:50 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.197 2012/11/05 17:24:11 dholland Exp $"); #include "opt_magiclinks.h" @@ -195,7 +195,7 @@ symlink_magic(struct proc *p, char *cp, //////////////////////////////////////////////////////////// /* - * Determine the namei hash (for cn_hash) for name. + * Determine the namei hash (for the namecache) for name. * If *ep != NULL, hash from name to ep-1. * If *ep == NULL, hash from name until the first NUL or '/', and * return the location of this termination character in *ep. @@ -222,6 +222,22 @@ namei_hash(const char *name, const char return (hash + (hash >> 5)); } +/* + * Find the end of the first path component in NAME and return its + * length. + */ +static size_t +namei_getcomponent(const char *name) +{ + size_t pos; + + pos = 0; + while (name[pos] != '\0' && name[pos] != '/') { + pos++; + } + return pos; +} + //////////////////////////////////////////////////////////// /* @@ -806,7 +822,6 @@ lookup_parsepath(struct namei_state *sta /* * Search a new directory. * - * The cn_hash value is for use by vfs_cache. * The last component of the filename is left accessible via * cnp->cn_nameptr for callers that need the name. Callers needing * the name set the SAVENAME flag. When done, they assume @@ -816,9 +831,8 @@ lookup_parsepath(struct namei_state *sta * is held and locked. */ cnp->cn_consume = 0; - cp = NULL; - cnp->cn_hash = namei_hash(cnp->cn_nameptr, &cp); - cnp->cn_namelen = cp - cnp->cn_nameptr; + cnp->cn_namelen = namei_getcomponent(cnp->cn_nameptr); + cp = cnp->cn_nameptr + cnp->cn_namelen; if (cnp->cn_namelen > KERNEL_NAME_MAX) { return ENAMETOOLONG; } @@ -1558,9 +1572,8 @@ do_lookup_for_nfsd_index(struct namei_st ndp->ni_dvp = NULL; cnp->cn_consume = 0; - cp = NULL; - cnp->cn_hash = namei_hash(cnp->cn_nameptr, &cp); - cnp->cn_namelen = cp - cnp->cn_nameptr; + cnp->cn_namelen = namei_getcomponent(cnp->cn_nameptr); + cp = cnp->cn_nameptr + cnp->cn_namelen; KASSERT(cnp->cn_namelen <= KERNEL_NAME_MAX); ndp->ni_pathlen -= cnp->cn_namelen; ndp->ni_next = cp; @@ -1656,8 +1669,8 @@ relookup(struct vnode *dvp, struct vnode int rdonly; /* lookup read-only flag bit */ int error = 0; #ifdef DEBUG - uint32_t newhash; /* DEBUG: check name hash */ - const char *cp; /* DEBUG: check name ptr/len */ + size_t newlen; /* DEBUG: check name len */ + const char *cp; /* DEBUG: check name ptr */ #endif /* DEBUG */ (void)dummy; @@ -1677,12 +1690,16 @@ relookup(struct vnode *dvp, struct vnode * responsibility for freeing the pathname buffer. */ #ifdef DEBUG +#if 0 cp = NULL; newhash = namei_hash(cnp->cn_nameptr, &cp); if ((uint32_t)newhash != (uint32_t)cnp->cn_hash) panic("relookup: bad hash"); - if (cnp->cn_namelen != cp - cnp->cn_nameptr) +#endif + newlen = nami_getcomponent(cnp->cn_nameptr); + if (cnp->cn_namelen != newlen) panic("relookup: bad len"); + cp = cnp->cn_nameptr + cnp->cn_namelen; while (*cp == '/') cp++; if (*cp != 0) Index: src/sys/nfs/nfs_vnops.c diff -u src/sys/nfs/nfs_vnops.c:1.295 src/sys/nfs/nfs_vnops.c:1.296 --- src/sys/nfs/nfs_vnops.c:1.295 Sun Jul 22 00:53:21 2012 +++ src/sys/nfs/nfs_vnops.c Mon Nov 5 17:24:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_vnops.c,v 1.295 2012/07/22 00:53:21 rmind Exp $ */ +/* $NetBSD: nfs_vnops.c,v 1.296 2012/11/05 17:24:11 dholland Exp $ */ /* * Copyright (c) 1989, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.295 2012/07/22 00:53:21 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.296 2012/11/05 17:24:11 dholland Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -780,6 +780,7 @@ nfs_lookup(void *v) long len; nfsfh_t *fhp; struct nfsnode *np; + int cachefound; int error = 0, attrflag, fhsize; const int v3 = NFS_ISV3(dvp); @@ -817,30 +818,24 @@ nfs_lookup(void *v) * the time the cache entry has been created. If it has, * the cache entry has to be ignored. */ - error = cache_lookup_raw(dvp, vpp, cnp); + cachefound = cache_lookup_raw(dvp, cnp, NULL, vpp); KASSERT(dvp != *vpp); KASSERT((cnp->cn_flags & ISWHITEOUT) == 0); - if (error >= 0) { + if (cachefound) { struct vattr vattr; - int err2; - if (error && error != ENOENT) { - *vpp = NULLVP; - return error; - } - - err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); - if (err2 != 0) { - if (error == 0) + error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); + if (error != 0) { + if (*vpp != NULLVP) vrele(*vpp); *vpp = NULLVP; - return err2; + return error; } if (VOP_GETATTR(dvp, &vattr, cnp->cn_cred) || timespeccmp(&vattr.va_mtime, &VTONFS(dvp)->n_nctime, !=)) { - if (error == 0) { + if (*vpp != NULLVP) { vrele(*vpp); *vpp = NULLVP; } @@ -849,7 +844,8 @@ nfs_lookup(void *v) goto dorpc; } - if (error == ENOENT) { + if (*vpp == NULLVP) { + /* namecache gave us a negative result */ goto noentry; } @@ -2777,18 +2773,12 @@ nfs_readdirplusrpc(struct vnode *vp, str newvp = NFSTOV(np); } if (!error) { - const char *xcp; - nfs_loadattrcache(&newvp, &fattr, 0, 0); if (bigenough) { dp->d_type = IFTODT(VTTOIF(np->n_vattr->va_type)); if (cnp->cn_namelen <= NCHNAMLEN) { ndp->ni_vp = newvp; - xcp = cnp->cn_nameptr + - cnp->cn_namelen; - cnp->cn_hash = - namei_hash(cnp->cn_nameptr, &xcp); nfs_cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp); } Index: src/sys/rump/librump/rumpvfs/rump_vfs.c diff -u src/sys/rump/librump/rumpvfs/rump_vfs.c:1.67 src/sys/rump/librump/rumpvfs/rump_vfs.c:1.68 --- src/sys/rump/librump/rumpvfs/rump_vfs.c:1.67 Mon Jul 4 11:31:37 2011 +++ src/sys/rump/librump/rumpvfs/rump_vfs.c Mon Nov 5 17:24:12 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: rump_vfs.c,v 1.67 2011/07/04 11:31:37 mrg Exp $ */ +/* $NetBSD: rump_vfs.c,v 1.68 2012/11/05 17:24:12 dholland Exp $ */ /* * Copyright (c) 2008 Antti Kantee. All Rights Reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.67 2011/07/04 11:31:37 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.68 2012/11/05 17:24:12 dholland Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -184,7 +184,6 @@ rump_makecn(u_long nameiop, u_long flags { struct rumpcn *rcn; struct componentname *cnp; - const char *cp = NULL; rcn = kmem_zalloc(sizeof(*rcn), KM_SLEEP); cnp = &rcn->rcn_cn; @@ -197,7 +196,6 @@ rump_makecn(u_long nameiop, u_long flags cnp->cn_flags = flags & (MODMASK | PARAMASK); cnp->cn_namelen = namelen; - cnp->cn_hash = namei_hash(name, &cp); cnp->cn_cred = creds; Index: src/sys/sys/namei.src diff -u src/sys/sys/namei.src:1.27 src/sys/sys/namei.src:1.28 --- src/sys/sys/namei.src:1.27 Sat Oct 13 17:46:50 2012 +++ src/sys/sys/namei.src Mon Nov 5 17:24:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: namei.src,v 1.27 2012/10/13 17:46:50 dholland Exp $ */ +/* $NetBSD: namei.src,v 1.28 2012/11/05 17:24:09 dholland Exp $ */ /* * Copyright (c) 1985, 1989, 1991, 1993 @@ -119,7 +119,6 @@ struct nameidata { */ const char *cn_nameptr; /* pointer to looked up name */ size_t cn_namelen; /* length of looked up comp */ - u_long cn_hash; /* hash val of looked up name */ size_t cn_consume; /* chars to consume in lookup */ } ni_cnd; }; @@ -264,9 +263,10 @@ void cache_purge1(struct vnode *, const #define PURGE_PARENTS 1 #define PURGE_CHILDREN 2 #define cache_purge(vp) cache_purge1((vp), NULL, PURGE_PARENTS|PURGE_CHILDREN) -int cache_lookup(struct vnode *, struct vnode **, struct componentname *); -int cache_lookup_raw(struct vnode *, struct vnode **, - struct componentname *); +int cache_lookup(struct vnode *, const struct componentname *, + int *, struct vnode **); +int cache_lookup_raw(struct vnode *, const struct componentname *, + int *, struct vnode **); int cache_revlookup(struct vnode *, struct vnode **, char **, char *); void cache_enter(struct vnode *, struct vnode *, struct componentname *); void nchinit(void); Index: src/sys/ufs/chfs/chfs_vnops.c diff -u src/sys/ufs/chfs/chfs_vnops.c:1.11 src/sys/ufs/chfs/chfs_vnops.c:1.12 --- src/sys/ufs/chfs/chfs_vnops.c:1.11 Fri Oct 19 12:44:39 2012 +++ src/sys/ufs/chfs/chfs_vnops.c Mon Nov 5 17:24:12 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: chfs_vnops.c,v 1.11 2012/10/19 12:44:39 ttoth Exp $ */ +/* $NetBSD: chfs_vnops.c,v 1.12 2012/11/05 17:24:12 dholland Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -86,8 +86,8 @@ chfs_lookup(void *v) /* Avoid doing a linear scan of the directory if the requested * directory/name couple is already in the cache. */ - error = cache_lookup(dvp, vpp, cnp); - if (error >= 0) { + if (cache_lookup(dvp, cnp, NULL, vpp)) { + error = *vpp == NULLVP ? ENOENT : 0; goto out; } Index: src/sys/ufs/ext2fs/ext2fs_lookup.c diff -u src/sys/ufs/ext2fs/ext2fs_lookup.c:1.70 src/sys/ufs/ext2fs/ext2fs_lookup.c:1.71 --- src/sys/ufs/ext2fs/ext2fs_lookup.c:1.70 Sun Jul 22 00:53:22 2012 +++ src/sys/ufs/ext2fs/ext2fs_lookup.c Mon Nov 5 17:24:12 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_lookup.c,v 1.70 2012/07/22 00:53:22 rmind Exp $ */ +/* $NetBSD: ext2fs_lookup.c,v 1.71 2012/11/05 17:24:12 dholland Exp $ */ /* * Modified for NetBSD 1.2E @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.70 2012/07/22 00:53:22 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.71 2012/11/05 17:24:12 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -325,8 +325,9 @@ ext2fs_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) - return (error); + if (cache_lookup(vdp, cnp, NULL, vpp)) { + return *vpp == NULLVP ? ENOENT : 0; + } /* * Suppress search for slots unless creating Index: src/sys/ufs/ufs/ufs_lookup.c diff -u src/sys/ufs/ufs/ufs_lookup.c:1.118 src/sys/ufs/ufs/ufs_lookup.c:1.119 --- src/sys/ufs/ufs/ufs_lookup.c:1.118 Sun Oct 14 23:57:32 2012 +++ src/sys/ufs/ufs/ufs_lookup.c Mon Nov 5 17:24:12 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_lookup.c,v 1.118 2012/10/14 23:57:32 dholland Exp $ */ +/* $NetBSD: ufs_lookup.c,v 1.119 2012/11/05 17:24:12 dholland Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.118 2012/10/14 23:57:32 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.119 2012/11/05 17:24:12 dholland Exp $"); #ifdef _KERNEL_OPT #include "opt_ffs.h" @@ -153,6 +153,7 @@ ufs_lookup(void *v) int dirblksiz = ump->um_dirblksiz; ino_t foundino; struct ufs_lookup_results *results; + int iswhiteout; /* temp result from cache_lookup() */ flags = cnp->cn_flags; @@ -186,8 +187,24 @@ ufs_lookup(void *v) * check the name cache to see if the directory/name pair * we are looking for is known already. */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) { - return (error); + if (cache_lookup(vdp, cnp, &iswhiteout, vpp)) { + if (iswhiteout) { + cnp->cn_flags |= ISWHITEOUT; + } + return *vpp == NULLVP ? ENOENT : 0; + } + if (iswhiteout) { + /* + * The namecache set iswhiteout without finding a + * cache entry. As of this writing (20121014), this + * can happen if there was a whiteout entry that has + * been invalidated by the lookup. It is not clear if + * it is correct to set ISWHITEOUT in this case or + * not; however, doing so retains the prior behavior, + * so we'll go with that until some clearer answer + * appears. XXX + */ + cnp->cn_flags |= ISWHITEOUT; } fstrans_start(vdp->v_mount, FSTRANS_SHARED);