introduce a new function, cache_lookup_raw(), for filesystems which

want more flexible namecache handling.
it just looks up a dnlc entry and vget() the result vnode.
ie. no automatic entry removal, no automatic vnode locking.

discussed on tech-kern@.
This commit is contained in:
yamt 2004-06-27 08:50:44 +00:00
parent 2c83b7a91b
commit ce02ffbc68
2 changed files with 76 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_cache.c,v 1.60 2004/06/19 18:49:47 yamt Exp $ */
/* $NetBSD: vfs_cache.c,v 1.61 2004/06/27 08:50:44 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.60 2004/06/19 18:49:47 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.61 2004/06/27 08:50:44 yamt Exp $");
#include "opt_ddb.h"
#include "opt_revcache.h"
@ -328,6 +328,77 @@ fail:
return (-1);
}
int
cache_lookup_raw(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp)
{
struct namecache *ncp;
struct vnode *vp;
int error;
if (!doingcache) {
cnp->cn_flags &= ~MAKEENTRY;
*vpp = NULL;
return (-1);
}
if (cnp->cn_namelen > NCHNAMLEN) {
/* XXXSMP - updating stats without lock; do we care? */
nchstats.ncs_long++;
cnp->cn_flags &= ~MAKEENTRY;
goto fail;
}
simple_lock(&namecache_slock);
ncp = cache_lookup_entry(dvp, cnp);
if (ncp == NULL) {
nchstats.ncs_miss++;
goto fail_wlock;
}
/*
* Move this slot to end of LRU chain,
* if not already there.
*/
if (TAILQ_NEXT(ncp, nc_lru) != 0) {
TAILQ_REMOVE(&nclruhead, ncp, nc_lru);
TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru);
}
vp = ncp->nc_vp;
if (vp == NULL) {
/*
* Restore the ISWHITEOUT flag saved earlier.
*/
cnp->cn_flags |= ncp->nc_flags;
nchstats.ncs_neghits++;
simple_unlock(&namecache_slock);
return (ENOENT);
}
error = vget(vp, LK_NOWAIT);
/* Release the name cache mutex while we get reference to the vnode */
simple_unlock(&namecache_slock);
if (error) {
KASSERT(error == EBUSY);
/*
* this vnode is being cleaned out.
*/
nchstats.ncs_falsehits++; /* XXX badhits? */
goto fail;
}
*vpp = vp;
return 0;
fail_wlock:
simple_unlock(&namecache_slock);
fail:
*vpp = NULL;
return -1;
}
/*
* Scan cache looking for name of directory entry pointing at vp.
*

View File

@ -1,4 +1,4 @@
/* $NetBSD: namei.h,v 1.36 2004/04/17 15:24:22 christos Exp $ */
/* $NetBSD: namei.h,v 1.37 2004/06/27 08:50:44 yamt Exp $ */
/*
* Copyright (c) 1985, 1989, 1991, 1993
@ -193,6 +193,8 @@ void cache_purge1 __P((struct vnode *, const struct componentname *, int));
#define PURGE_CHILDREN 2
#define cache_purge(vp) cache_purge1((vp), NULL, PURGE_PARENTS|PURGE_CHILDREN)
int cache_lookup __P((struct vnode *, struct vnode **, struct componentname *));
int cache_lookup_raw __P((struct vnode *, struct vnode **,
struct componentname *));
int cache_revlookup __P((struct vnode *, struct vnode **, char **, char *));
void cache_enter __P((struct vnode *, struct vnode *, struct componentname *));
void nchinit __P((void));