tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: excising struct componentname from the namecache
On Mon, Oct 15, 2012 at 11:10 AM, David Holland
<dholland-tech%netbsd.org@localhost> wrote:
> In the long-term interests of making struct componentname go away
> entirely, here's the next step in namei-related cleanup.
>
> This patch: (1) moves the namecache's hash computation inside the
> namecache, instead of being spread around all over everywhere; (2)
> fixes the namecache to no longer require write access to cn_flags;
> (3) reorganizes the calling conventions for cache_lookup (and
> cache_raw_lookup) to be more robust; and (4) avoids passing struct
> componentname into the namecache at all.
>
> Note that the interface to cache_lookup is not as tidy (especially
> since for the time being, it requires access to cn_nameiop) but this
> should improve in the future as the special-case handling for
> directory ops is pried apart from the primary lookup logic.
>
> These four pieces are available as separate patches, but since nobody
> seems to be interested in that, the following is all of them rolled
> together.
Can you fix zfs, too ? Or I can fix it after your commit.
http://nxr.netbsd.org/xref/src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c#zfs_lookup
http://nxr.netbsd.org/xref/src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c#1367
http://nxr.netbsd.org/xref/src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c#1371
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/cd9660/cd9660_lookup.c
> --- a/sys/fs/cd9660/cd9660_lookup.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/cd9660/cd9660_lookup.c Mon Oct 15 05:06:00 2012 -0400
> @@ -151,8 +151,10 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, NULL, vpp)) {
> + return *vpp == NULLVP ? ENOENT : 0;
> + }
>
> len = cnp->cn_namelen;
> name = cnp->cn_nameptr;
> @@ -336,7 +338,7 @@
> /*
> * Insert name into cache (as non-existent) if appropriate.
> */
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> cnp->cn_flags);
> return (nameiop == CREATE || nameiop == RENAME) ? EROFS : ENOENT;
>
> found:
> @@ -399,7 +401,7 @@
> /*
> * Insert name into cache if appropriate.
> */
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> cnp->cn_flags);
> return 0;
> }
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/efs/efs_vnops.c
> --- a/sys/fs/efs/efs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/efs/efs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -73,9 +73,10 @@
> 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, NULL, ap->a_vpp)) {
> + return *ap->a_vpp == NULLVP ? ENOENT : 0;
> + }
>
> /*
> * Handle the three lookup types: '.', '..', and everything else.
> @@ -103,7 +104,8 @@
> EFS_VTOI(ap->a_dvp), ap->a_cnp, &ino);
> if (err) {
> if (err == ENOENT && nameiop != CREATE)
> - cache_enter(ap->a_dvp, NULL, cnp);
> + cache_enter(ap->a_dvp, NULL, cnp->cn_nameptr,
> + cnp->cn_namelen, cnp->cn_flags);
> if (err == ENOENT && (nameiop == CREATE ||
> nameiop == RENAME)) {
> err = VOP_ACCESS(ap->a_dvp, VWRITE,
> @@ -120,7 +122,8 @@
> *ap->a_vpp = vp;
> }
>
> - cache_enter(ap->a_dvp, *ap->a_vpp, cnp);
> + cache_enter(ap->a_dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> return 0;
> }
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/msdosfs/msdosfs_lookup.c
> --- a/sys/fs/msdosfs/msdosfs_lookup.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/msdosfs/msdosfs_lookup.c Mon Oct 15 05:06:00 2012 -0400
> @@ -146,8 +146,10 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, NULL, vpp)) {
> + return *vpp == NULLVP ? ENOENT: 0;
> + }
>
> /*
> * If they are going after the . or .. entry in the root directory,
> @@ -400,7 +402,8 @@
> * for 'FOO'.
> */
> if (nameiop != CREATE)
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
> #endif
>
> return (ENOENT);
> @@ -553,7 +556,7 @@
> /*
> * Insert name into cache if appropriate.
> */
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> cnp->cn_flags);
>
> return 0;
> }
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/nilfs/nilfs_vnops.c
> --- a/sys/fs/nilfs/nilfs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/nilfs/nilfs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -652,10 +652,11 @@
>
> 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, NULL, vpp)) {
> + return *vpp == NULLVP ? ENOENT : 0;
> + }
>
> DPRINTF(LOOKUP, ("\tNOT found in cache\n"));
>
> @@ -761,7 +762,8 @@
> * might be seen as negative caching.
> */
> if (nameiop != CREATE)
> - cache_enter(dvp, *vpp, cnp);
> + cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> DPRINTFIF(LOOKUP, error, ("nilfs_lookup returing error %d\n", error));
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/ntfs/ntfs_vnops.c
> --- a/sys/fs/ntfs/ntfs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/ntfs/ntfs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -682,8 +682,10 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, 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",
> @@ -725,7 +727,8 @@
> (unsigned long long)VTONT(*ap->a_vpp)->i_number));
> }
>
> - cache_enter(dvp, *ap->a_vpp, cnp);
> + cache_enter(dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> return error;
> }
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/puffs/puffs_msgif.c
> --- a/sys/fs/puffs/puffs_msgif.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/puffs/puffs_msgif.c Mon Oct 15 05:06:00 2012 -0400
> @@ -915,7 +915,7 @@
> rv = EINVAL;
> break;
> }
> - cache_purge1(vp, NULL, PURGE_CHILDREN);
> + cache_purge1(vp, NULL, 0, PURGE_CHILDREN);
> break;
>
> case PUFFS_INVAL_PAGECACHE_NODE_RANGE:
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/puffs/puffs_node.c
> --- a/sys/fs/puffs/puffs_node.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/puffs/puffs_node.c Mon Oct 15 05:06:00 2012 -0400
> @@ -247,7 +247,8 @@
> *vpp = vp;
>
> if (PUFFS_USE_NAMECACHE(pmp))
> - cache_enter(dvp, vp, cnp);
> + cache_enter(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> return 0;
> }
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/puffs/puffs_vnops.c
> --- a/sys/fs/puffs/puffs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/puffs/puffs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -526,9 +526,16 @@
> * Check if someone fed it into the cache
> */
> if (!isdot && PUFFS_USE_NAMECACHE(pmp)) {
> - error = cache_lookup(dvp, ap->a_vpp, cnp);
> -
> - if ((error == 0) && PUFFS_USE_FS_TTL(pmp)) {
> + int found, iswhiteout;
> +
> + found = cache_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags,
> + &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 +547,7 @@
> * successful lookup.
> */
> *ap->a_vpp = NULL;
> - error = -1;
> + found = 0;
> }
> }
>
> @@ -548,11 +555,20 @@
> * Do not use negative caching, since the filesystem
> * provides no TTL for it.
> */
> - if ((error == ENOENT) && PUFFS_USE_FS_TTL(pmp))
> - error = -1;
> -
> - if (error >= 0)
> - return error;
> + if (found && *ap->a_vpp == NULLVP && PUFFS_USE_FS_TTL(pmp))
> + found = 0;
> +
> + 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) {
> @@ -606,7 +622,8 @@
> } else {
> if (PUFFS_USE_NAMECACHE(pmp) &&
> !PUFFS_USE_FS_TTL(pmp))
> - cache_enter(dvp, NULL, cnp);
> + cache_enter(dvp, NULL,
> cnp->cn_nameptr,
> + cnp->cn_namelen,
> cnp->cn_flags);
> }
> }
> goto out;
> @@ -682,7 +699,8 @@
> *ap->a_vpp = vp;
>
> if (PUFFS_USE_NAMECACHE(pmp))
> - cache_enter(dvp, vp, cnp);
> + cache_enter(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> /* XXX */
> if ((lookup_msg->pvnr_cn.pkcn_flags & REQUIREDIR) == 0)
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/smbfs/smbfs_vnops.c
> --- a/sys/fs/smbfs/smbfs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/smbfs/smbfs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -596,7 +596,8 @@
> if (error)
> goto out;
>
> - cache_enter(dvp, *ap->a_vpp, cnp);
> + cache_enter(dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> out:
> VN_KNOTE(dvp, NOTE_WRITE);
> @@ -1202,29 +1203,25 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags,
> + 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;
> @@ -1297,7 +1294,8 @@
> * Insert name into cache (as non-existent) if appropriate.
> */
> if (nameiop != CREATE)
> - cache_enter(dvp, *vpp, cnp);
> + cache_enter(dvp, *vpp, cnp->cn_nameptr,
> cnp->cn_namelen,
> + cnp->cn_flags);
>
> return (ENOENT);
> }
> @@ -1352,11 +1350,13 @@
> KASSERT(error == 0);
> if (cnp->cn_nameiop != DELETE || !islastcn) {
> VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_mtime.tv_sec;
> - cache_enter(dvp, *vpp, cnp);
> + cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
> #ifdef notdef
> } else if (error == ENOENT && cnp->cn_nameiop != CREATE) {
> VTOSMB(*vpp)->n_nctime = VTOSMB(*vpp)->n_mtime.tv_sec;
> - cache_enter(dvp, *vpp, cnp);
> + cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
> #endif
> }
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/tmpfs/tmpfs_vnops.c
> --- a/sys/fs/tmpfs/tmpfs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/tmpfs/tmpfs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -133,6 +133,7 @@
> 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,18 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags,
> + &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;
> }
>
> @@ -278,7 +288,8 @@
> * not improve the performance).
> */
> if (cnp->cn_nameiop != CREATE) {
> - cache_enter(dvp, *vpp, cnp);
> + cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
> }
> out:
> KASSERT((*vpp && VOP_ISLOCKED(*vpp)) || error);
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/udf/udf_vnops.c
> --- a/sys/fs/udf/udf_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/udf/udf_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -687,10 +687,11 @@
>
> 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, NULL, vpp)) {
> + return *vpp == NULLVP ? ENOENT : 0;
> + }
>
> DPRINTF(LOOKUP, ("\tNOT found in cache\n"));
>
> @@ -796,7 +797,8 @@
> * might be seen as negative caching.
> */
> if (nameiop != CREATE)
> - cache_enter(dvp, *vpp, cnp);
> + cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
>
> DPRINTFIF(LOOKUP, error, ("udf_lookup returing error %d\n", error));
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/union/union.h
> --- a/sys/fs/union/union.h Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/union/union.h Mon Oct 15 05:06:00 2012 -0400
> @@ -126,7 +126,6 @@
> 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 */
> diff -r cba39a555764 -r 42d43ac83fe1 sys/fs/union/union_subr.c
> --- a/sys/fs/union/union_subr.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/fs/union/union_subr.c Mon Oct 15 05:06:00 2012 -0400
> @@ -105,7 +105,7 @@
> 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 @@
> 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 @@
> 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 @@
> */
> 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 @@
> 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 @@
> 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 @@
>
> 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 @@
> 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 @@
> 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;
> diff -r cba39a555764 -r 42d43ac83fe1 sys/kern/vfs_cache.c
> --- a/sys/kern/vfs_cache.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/kern/vfs_cache.c Mon Oct 15 05:06:00 2012 -0400
> @@ -109,6 +109,16 @@
> };
>
> /*
> + * 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 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;
> @@ -151,7 +161,7 @@
>
> static void cache_invalidate(struct namecache *);
> static struct namecache *cache_lookup_entry(
> - const struct vnode *, const struct componentname *);
> + const struct vnode *, const char *, size_t);
> static void cache_thread(void *);
> static void cache_invalidate(struct namecache *);
> static void cache_disassociate(struct namecache *);
> @@ -160,6 +170,21 @@
> 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 char *name, size_t namelen)
> +{
> + const char *endptr;
> +
> + endptr = name + namelen;
> + return namei_hash(name, &endptr);
> +}
> +
> +/*
> * Invalidate a cache entry and enqueue it for garbage collection.
> */
> static void
> @@ -257,18 +282,20 @@
> * at least one of the per-CPU locks must be held.
> */
> static struct namecache *
> -cache_lookup_entry(const struct vnode *dvp, const struct componentname *cnp)
> +cache_lookup_entry(const struct vnode *dvp, const char *name, size_t namelen)
> {
> struct nchashhead *ncpp;
> struct namecache *ncp;
> + nchash_t hash;
>
> KASSERT(dvp != NULL);
> - ncpp = &nchashtbl[NCHASH(cnp, dvp)];
> + hash = cache_hash(name, namelen);
> + ncpp = &nchashtbl[NCHASH2(hash, dvp)];
>
> LIST_FOREACH(ncp, ncpp, nc_hash) {
> if (ncp->nc_dvp != dvp ||
> - ncp->nc_nlen != cnp->cn_namelen ||
> - memcmp(ncp->nc_name, cnp->cn_nameptr,
> (u_int)ncp->nc_nlen))
> + ncp->nc_nlen != namelen ||
> + memcmp(ncp->nc_name, name, (u_int)ncp->nc_nlen))
> continue;
> mutex_enter(&ncp->nc_lock);
> if (__predict_true(ncp->nc_dvp == dvp)) {
> @@ -288,47 +315,86 @@
> * 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 char *name, size_t namelen,
> + uint32_t nameiop, uint32_t cnflags,
> + 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)) {
> + if (__predict_false(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);
> + ncp = cache_lookup_entry(dvp, name, namelen);
> 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) {
> + if ((cnflags & MAKEENTRY) == 0) {
> COUNT(cpup->cpu_stats, ncs_badhits);
> /*
> * Last component and we are renaming or deleting,
> @@ -338,20 +404,27 @@
> 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;
> - if (__predict_true(cnp->cn_nameiop != CREATE ||
> - (cnp->cn_flags & ISLASTCN) == 0)) {
> + /* 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);
> + *iswht_ret = (ncp->nc_flags & ISWHITEOUT) != 0;
> + } else {
> + KASSERT(ncp->nc_flags == 0);
> + }
> +
> + if (__predict_true(nameiop != CREATE ||
> + (cnflags & 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_invalidate(ncp);
> mutex_exit(&ncp->nc_lock);
> mutex_exit(&cpup->cpu_lock);
> - *vpp = NULL;
> - return -1;
> + /* found nothing */
> + return 0;
> }
> }
>
> @@ -384,8 +457,8 @@
> * XXX badhits?
> */
> COUNT(cpup->cpu_stats, ncs_falsehits);
> - *vpp = NULL;
> - return -1;
> + /* found nothing */
> + return 0;
> }
> }
>
> @@ -399,7 +472,7 @@
>
> if (vp == dvp) { /* lookup on "." */
> error = 0;
> - } else if (cnp->cn_flags & ISDOTDOT) {
> + } else if (cnflags & ISDOTDOT) {
> VOP_UNLOCK(dvp);
> error = vn_lock(vp, LK_EXCLUSIVE);
> vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
> @@ -411,61 +484,73 @@
> * 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 char *name, size_t namelen,
> + uint32_t cnflags,
> + 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)) {
> + if (__predict_false(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);
> + ncp = cache_lookup_entry(dvp, name, namelen);
> 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 +567,17 @@
> * 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;
> }
>
> /*
> @@ -584,16 +671,18 @@
> * Add an entry to the cache
> */
> void
> -cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
> +cache_enter(struct vnode *dvp, struct vnode *vp,
> + const char *name, size_t namelen, uint32_t cnflags)
> {
> struct namecache *ncp;
> 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 ||
> - __predict_false(cnp->cn_namelen > NCHNAMLEN || !doingcache)) {
> + if ((cnflags & MAKEENTRY) == 0 ||
> + __predict_false(namelen > NCHNAMLEN || !doingcache)) {
> return;
> }
>
> @@ -612,7 +701,7 @@
> * Concurrent lookups in the same directory may race for a
> * cache entry. if there's a duplicated entry, free it.
> */
> - oncp = cache_lookup_entry(dvp, cnp);
> + oncp = cache_lookup_entry(dvp, name, namelen);
> if (oncp) {
> cache_invalidate(oncp);
> mutex_exit(&oncp->nc_lock);
> @@ -629,7 +718,7 @@
> * For negative hits, save the ISWHITEOUT flag so we can
> * restore it later when the cache entry is used again.
> */
> - ncp->nc_flags = cnp->cn_flags & ISWHITEOUT;
> + ncp->nc_flags = cnflags & ISWHITEOUT;
> }
>
> /* Fill in cache info. */
> @@ -641,11 +730,12 @@
> ncp->nc_vlist.le_prev = NULL;
> ncp->nc_vlist.le_next = NULL;
> }
> - KASSERT(cnp->cn_namelen <= NCHNAMLEN);
> - ncp->nc_nlen = cnp->cn_namelen;
> - memcpy(ncp->nc_name, cnp->cn_nameptr, (unsigned)ncp->nc_nlen);
> + KASSERT(namelen <= NCHNAMLEN);
> + ncp->nc_nlen = namelen;
> + memcpy(ncp->nc_name, name, (unsigned)ncp->nc_nlen);
> TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru);
> - ncpp = &nchashtbl[NCHASH(cnp, dvp)];
> + hash = cache_hash(name, namelen);
> + ncpp = &nchashtbl[NCHASH2(hash, dvp)];
>
> /*
> * Flush updates before making visible in table. No need for a
> @@ -810,7 +900,7 @@
> * hide entries that would now be invalid
> */
> void
> -cache_purge1(struct vnode *vp, const struct componentname *cnp, int flags)
> +cache_purge1(struct vnode *vp, const char *name, size_t namelen, int flags)
> {
> struct namecache *ncp, *ncnext;
>
> @@ -835,8 +925,8 @@
> cache_disassociate(ncp);
> }
> }
> - if (cnp != NULL) {
> - ncp = cache_lookup_entry(vp, cnp);
> + if (name != NULL) {
> + ncp = cache_lookup_entry(vp, name, namelen);
> if (ncp) {
> cache_invalidate(ncp);
> mutex_exit(&ncp->nc_lock);
> diff -r cba39a555764 -r 42d43ac83fe1 sys/kern/vfs_getcwd.c
> --- a/sys/kern/vfs_getcwd.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/kern/vfs_getcwd.c Mon Oct 15 05:06:00 2012 -0400
> @@ -130,7 +130,6 @@
> cn.cn_cred = cred;
> cn.cn_nameptr = "..";
> cn.cn_namelen = 2;
> - cn.cn_hash = 0;
> cn.cn_consume = 0;
>
> /*
> diff -r cba39a555764 -r 42d43ac83fe1 sys/kern/vfs_lookup.c
> --- a/sys/kern/vfs_lookup.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/kern/vfs_lookup.c Mon Oct 15 05:06:00 2012 -0400
> @@ -195,7 +195,7 @@
> ////////////////////////////////////////////////////////////
>
> /*
> - * 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 @@
> 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 @@
> /*
> * 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 @@
> * 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 @@
> 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 @@
> 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 @@
> * 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)
> diff -r cba39a555764 -r 42d43ac83fe1 sys/nfs/nfs_vnops.c
> --- a/sys/nfs/nfs_vnops.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/nfs/nfs_vnops.c Mon Oct 15 05:06:00 2012 -0400
> @@ -279,7 +279,7 @@
> if (!timespecisset(&dnp->n_nctime))
> dnp->n_nctime = dnp->n_vattr->va_mtime;
>
> - cache_enter(dvp, vp, cnp);
> + cache_enter(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags);
> }
>
> /*
> @@ -780,6 +780,7 @@
> long len;
> nfsfh_t *fhp;
> struct nfsnode *np;
> + int cachefound;
> int error = 0, attrflag, fhsize;
> const int v3 = NFS_ISV3(dvp);
>
> @@ -817,39 +818,35 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags, 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) {
> + error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
> + if (error != 0) {
> + if (*vpp != NULLVP)
> + vrele(*vpp);
> *vpp = NULLVP;
> return error;
> }
>
> - err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
> - if (err2 != 0) {
> - if (error == 0)
> - vrele(*vpp);
> - *vpp = NULLVP;
> - return err2;
> - }
> -
> 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;
> }
> - cache_purge1(dvp, NULL, PURGE_CHILDREN);
> + cache_purge1(dvp, NULL, 0, PURGE_CHILDREN);
> timespecclear(&np->n_nctime);
> goto dorpc;
> }
>
> - if (error == ENOENT) {
> + if (*vpp == NULLVP) {
> + /* namecache gave us a negative result */
> goto noentry;
> }
>
> @@ -877,7 +874,7 @@
> KASSERT(newvp->v_type != VNON);
> return (0);
> }
> - cache_purge1(newvp, NULL, PURGE_PARENTS);
> + cache_purge1(newvp, NULL, 0, PURGE_PARENTS);
> vput(newvp);
> *vpp = NULLVP;
> }
> @@ -1581,7 +1578,7 @@
> error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, ap->a_vap);
> VN_KNOTE(dvp, NOTE_WRITE);
> if (error == 0 || error == EEXIST)
> - cache_purge1(dvp, cnp, 0);
> + cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
> return (error);
> }
>
> @@ -1708,13 +1705,13 @@
> if (cnp->cn_flags & MAKEENTRY)
> nfs_cache_enter(dvp, newvp, cnp);
> else
> - cache_purge1(dvp, cnp, 0);
> + cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen,
> 0);
> *ap->a_vpp = newvp;
> } else {
> if (newvp)
> vput(newvp);
> if (error == EEXIST)
> - cache_purge1(dvp, cnp, 0);
> + cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen,
> 0);
> }
> VTONFS(dvp)->n_flag |= NMODIFIED;
> if (!wccflag)
> @@ -1904,11 +1901,13 @@
> if (fvp->v_type == VDIR)
> cache_purge(fvp);
> else
> - cache_purge1(fdvp, fcnp, 0);
> + cache_purge1(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
> + 0);
> if (tvp != NULL && tvp->v_type == VDIR)
> cache_purge(tvp);
> else
> - cache_purge1(tdvp, tcnp, 0);
> + cache_purge1(tdvp, tcnp->cn_nameptr, tcnp->cn_namelen,
> + 0);
> }
> out:
> if (tdvp == tvp)
> @@ -2069,7 +2068,7 @@
> cnp->cn_cred, curlwp);
>
> if (error == 0) {
> - cache_purge1(dvp, cnp, 0);
> + cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
> }
> VOP_UNLOCK(vp);
> VN_KNOTE(vp, NOTE_LINK);
> @@ -2145,7 +2144,7 @@
> if (rexmit && error == EEXIST)
> error = 0;
> if (error == 0 || error == EEXIST)
> - cache_purge1(dvp, cnp, 0);
> + cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
> if (error == 0 && newvp == NULL) {
> struct nfsnode *np = NULL;
>
> @@ -2777,18 +2776,12 @@
> 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);
> }
> diff -r cba39a555764 -r 42d43ac83fe1 sys/rump/include/rump/rump_namei.h
> --- a/sys/rump/include/rump/rump_namei.h Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/rump/include/rump/rump_namei.h Mon Oct 15 05:06:00 2012 -0400
> @@ -1,4 +1,4 @@
> -/* $NetBSD: rump_namei.h,v 1.18 2012/10/13 17:47:11 dholland Exp $ */
> +/* $NetBSD: gennameih.awk,v 1.5 2009/12/23 14:17:19 pooka Exp $ */
>
>
> /*
> diff -r cba39a555764 -r 42d43ac83fe1 sys/rump/librump/rumpvfs/rump_vfs.c
> --- a/sys/rump/librump/rumpvfs/rump_vfs.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/rump/librump/rumpvfs/rump_vfs.c Mon Oct 15 05:06:00 2012 -0400
> @@ -184,7 +184,6 @@
> {
> 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 @@
> cnp->cn_flags = flags & (MODMASK | PARAMASK);
>
> cnp->cn_namelen = namelen;
> - cnp->cn_hash = namei_hash(name, &cp);
>
> cnp->cn_cred = creds;
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/sys/namei.h
> --- a/sys/sys/namei.h Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/sys/namei.h Mon Oct 15 05:06:00 2012 -0400
> @@ -1,4 +1,4 @@
> -/* $NetBSD: namei.h,v 1.82 2012/10/13 17:47:11 dholland Exp $ */
> +/* $NetBSD: gennameih.awk,v 1.5 2009/12/23 14:17:19 pooka Exp $ */
>
>
> /*
> @@ -127,7 +127,6 @@
> */
> 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;
> };
> @@ -268,15 +267,17 @@
> int lookup_for_nfsd(struct nameidata *, struct vnode *, int neverfollow);
> int lookup_for_nfsd_index(struct nameidata *, struct vnode *);
> int relookup(struct vnode *, struct vnode **, struct componentname *,
> int);
> -void cache_purge1(struct vnode *, const struct componentname *, int);
> +void cache_purge1(struct vnode *, const char *, size_t, int);
> #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 *);
> +#define cache_purge(vp)
> cache_purge1((vp),NULL,0,PURGE_PARENTS|PURGE_CHILDREN)
> +int cache_lookup(struct vnode *, const char *, size_t, uint32_t, uint32_t,
> + int *, struct vnode **);
> +int cache_lookup_raw(struct vnode *, const char *, size_t, uint32_t,
> + int *, struct vnode **);
> int cache_revlookup(struct vnode *, struct vnode **, char **, char *);
> -void cache_enter(struct vnode *, struct vnode *, struct componentname *);
> +void cache_enter(struct vnode *, struct vnode *,
> + const char *, size_t, uint32_t);
> void nchinit(void);
> void nchreinit(void);
> void cache_cpu_init(struct cpu_info *);
> diff -r cba39a555764 -r 42d43ac83fe1 sys/sys/namei.src
> --- a/sys/sys/namei.src Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/sys/namei.src Mon Oct 15 05:06:00 2012 -0400
> @@ -119,7 +119,6 @@
> */
> 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;
> };
> @@ -260,15 +259,17 @@
> int lookup_for_nfsd(struct nameidata *, struct vnode *, int neverfollow);
> int lookup_for_nfsd_index(struct nameidata *, struct vnode *);
> int relookup(struct vnode *, struct vnode **, struct componentname *,
> int);
> -void cache_purge1(struct vnode *, const struct componentname *, int);
> +void cache_purge1(struct vnode *, const char *, size_t, int);
> #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 *);
> +#define cache_purge(vp)
> cache_purge1((vp),NULL,0,PURGE_PARENTS|PURGE_CHILDREN)
> +int cache_lookup(struct vnode *, const char *, size_t, uint32_t, uint32_t,
> + int *, struct vnode **);
> +int cache_lookup_raw(struct vnode *, const char *, size_t, uint32_t,
> + int *, struct vnode **);
> int cache_revlookup(struct vnode *, struct vnode **, char **, char *);
> -void cache_enter(struct vnode *, struct vnode *, struct componentname *);
> +void cache_enter(struct vnode *, struct vnode *,
> + const char *, size_t, uint32_t);
> void nchinit(void);
> void nchreinit(void);
> void cache_cpu_init(struct cpu_info *);
> diff -r cba39a555764 -r 42d43ac83fe1 sys/ufs/ext2fs/ext2fs_lookup.c
> --- a/sys/ufs/ext2fs/ext2fs_lookup.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/ufs/ext2fs/ext2fs_lookup.c Mon Oct 15 05:06:00 2012 -0400
> @@ -325,8 +325,10 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, NULL, vpp)) {
> + return *vpp == NULLVP ? ENOENT : 0;
> + }
>
> /*
> * Suppress search for slots unless creating
> @@ -539,7 +541,8 @@
> * Insert name into cache (as non-existent) if appropriate.
> */
> if (nameiop != CREATE) {
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
> }
> return ENOENT;
>
> @@ -699,7 +702,7 @@
> /*
> * Insert name into cache if appropriate.
> */
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> cnp->cn_flags);
> return 0;
> }
>
> diff -r cba39a555764 -r 42d43ac83fe1 sys/ufs/ufs/ufs_lookup.c
> --- a/sys/ufs/ufs/ufs_lookup.c Sun Oct 14 23:09:40 2012 -0400
> +++ b/sys/ufs/ufs/ufs_lookup.c Mon Oct 15 05:06:00 2012 -0400
> @@ -153,6 +153,7 @@
> 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,25 @@
> * 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->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_nameiop, cnp->cn_flags, &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);
> @@ -497,7 +515,8 @@
> * Insert name into cache (as non-existent) if appropriate.
> */
> if (nameiop != CREATE) {
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> + cnp->cn_flags);
> }
> error = ENOENT;
> goto out;
> @@ -661,7 +680,7 @@
> /*
> * Insert name into cache if appropriate.
> */
> - cache_enter(vdp, *vpp, cnp);
> + cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
> cnp->cn_flags);
> error = 0;
>
> out:
>
>
> --
> David A. Holland
> dholland%netbsd.org@localhost
>
--
Regards.
Adam
Home |
Main Index |
Thread Index |
Old Index