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 <[email protected]>
@@ -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);