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:
parent
2c83b7a91b
commit
ce02ffbc68
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue