* Implement optional 32 <-> 64 bit directory cookie translation. This uses
the directory cache as translation table. See nfs_subs.c for comments. Makes the code a bit more complex to look at than I would have liked, but doesn't affect the speed of the default behavior. * Optimize caching behavior a bit when buffers are invalidated. * Save some RPCs in readdir operations by not bothering if there is a small amount left to do to fill the buffer. It'll be done in the next RPC with a larger chunk anyway. Wastes a bit of buffer space but is faster. * Make n_vattr an allocated vattr struct. This avoids nfsnode bloat, and is friendlier to the malloc routines.
This commit is contained in:
parent
adecb9addf
commit
1cf3a3db94
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs.h,v 1.16 1997/10/10 01:53:17 fvdl Exp $ */
|
||||
/* $NetBSD: nfs.h,v 1.17 1997/10/19 01:46:15 fvdl Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -328,7 +328,7 @@ TAILQ_HEAD(, nfsreq) nfs_reqq;
|
|||
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
|
||||
|
||||
#ifndef NFS_DIRHASHSIZ
|
||||
#define NFS_DIRHASHSIZ 32
|
||||
#define NFS_DIRHASHSIZ 64
|
||||
#endif
|
||||
#define NFSDIRHASH(np, off) \
|
||||
(&np->n_dircache[(nfs_dirhash((off)) & nfsdirhashmask)])
|
||||
|
@ -340,11 +340,11 @@ TAILQ_HEAD(, nfsreq) nfs_reqq;
|
|||
*((off_t *)((caddr_t)(dp) + (dp)->d_reclen - sizeof (off_t))) = off
|
||||
#define NFS_GETCOOKIE(dp) \
|
||||
(*((off_t *)((caddr_t)(dp) + (dp)->d_reclen - sizeof (off_t))))
|
||||
#define NFS_MARKCACHED(dp, val) \
|
||||
*((int *)((caddr_t)(dp) + (dp)->d_reclen - sizeof (off_t) - \
|
||||
#define NFS_STASHCOOKIE32(dp, val) \
|
||||
*((u_int32_t *)((caddr_t)(dp) + (dp)->d_reclen - sizeof (off_t) - \
|
||||
sizeof (int))) = val
|
||||
#define NFS_ISCACHED(dp) \
|
||||
(*((int *)((caddr_t)(dp) + (dp)->d_reclen - sizeof (off_t) - \
|
||||
#define NFS_GETCOOKIE32(dp) \
|
||||
(*((u_int32_t *)((caddr_t)(dp) + (dp)->d_reclen - sizeof (off_t) - \
|
||||
sizeof (int))))
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_bio.c,v 1.34 1997/10/10 01:53:18 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_bio.c,v 1.35 1997/10/19 01:46:20 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -82,7 +82,7 @@ nfs_bioread(vp, uio, ioflag, cred, cflag)
|
|||
struct vattr vattr;
|
||||
struct proc *p;
|
||||
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
|
||||
struct nfsdircache *ndp = NULL;
|
||||
struct nfsdircache *ndp = NULL, *nndp = NULL;
|
||||
daddr_t lbn, bn, rabn;
|
||||
caddr_t baddr, ep, edp;
|
||||
int got_buf = 0, nra, error = 0, n = 0, on = 0, not_readin, en, enn;
|
||||
|
@ -128,7 +128,8 @@ nfs_bioread(vp, uio, ioflag, cred, cflag)
|
|||
if (vp->v_type != VREG) {
|
||||
if (vp->v_type != VDIR)
|
||||
panic("nfs: bioread, not dir");
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
np->n_direofoffset = 0;
|
||||
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
|
||||
if (error)
|
||||
return (error);
|
||||
|
@ -143,8 +144,10 @@ nfs_bioread(vp, uio, ioflag, cred, cflag)
|
|||
if (error)
|
||||
return (error);
|
||||
if (np->n_mtime != vattr.va_mtime.tv_sec) {
|
||||
if (vp->v_type == VDIR)
|
||||
nfs_invaldircache(vp);
|
||||
if (vp->v_type == VDIR) {
|
||||
nfs_invaldircache(vp, 0);
|
||||
np->n_direofoffset = 0;
|
||||
}
|
||||
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
|
||||
if (error)
|
||||
return (error);
|
||||
|
@ -167,16 +170,19 @@ nfs_bioread(vp, uio, ioflag, cred, cflag)
|
|||
if (np->n_lrev != np->n_brev ||
|
||||
(np->n_flag & NQNFSNONCACHE) ||
|
||||
((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) {
|
||||
if (vp->v_type == VDIR)
|
||||
nfs_invaldircache(vp);
|
||||
if (vp->v_type == VDIR) {
|
||||
nfs_invaldircache(vp, 0);
|
||||
np->n_direofoffset = 0;
|
||||
}
|
||||
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
|
||||
if (error)
|
||||
return (error);
|
||||
np->n_brev = np->n_lrev;
|
||||
}
|
||||
} else if (vp->v_type == VDIR && (np->n_flag & NMODIFIED)) {
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
|
||||
np->n_direofoffset = 0;
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
|
@ -304,20 +310,37 @@ again:
|
|||
case VDIR:
|
||||
diragain:
|
||||
nfsstats.biocache_readdirs++;
|
||||
ndp = nfs_searchdircache(vp, uio->uio_offset,
|
||||
(nmp->nm_flag & NFSMNT_XLATECOOKIE), 0);
|
||||
if (!ndp) {
|
||||
/*
|
||||
* We've been handed a cookie that is not
|
||||
* in the cache. If we're not translating
|
||||
* 32 <-> 64, it may be a value that was
|
||||
* flushed out of the cache because it grew
|
||||
* too big. Let the server judge if it's
|
||||
* valid or not. In the translation case,
|
||||
* we have no way of validating this value,
|
||||
* so punt.
|
||||
*/
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE)
|
||||
return (EINVAL);
|
||||
ndp = nfs_enterdircache(vp, uio->uio_offset,
|
||||
uio->uio_offset, 0, 0);
|
||||
}
|
||||
|
||||
if (uio->uio_offset != 0 &&
|
||||
uio->uio_offset == np->n_direofoffset)
|
||||
ndp->dc_cookie == np->n_direofoffset) {
|
||||
nfsstats.direofcache_hits++;
|
||||
return (0);
|
||||
ndp = nfs_lookdircache(vp, uio->uio_offset, 0, 0, 1);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (!ndp)
|
||||
panic("nfs_bioread: bad dir cache");
|
||||
#endif
|
||||
}
|
||||
|
||||
bp = nfs_getcacheblk(vp, ndp->dc_blkno, NFS_DIRBLKSIZ, p);
|
||||
if (!bp)
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_DONE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_dcookie = ndp->dc_cookie;
|
||||
bp->b_dcookie = ndp->dc_blkcookie;
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error) {
|
||||
/*
|
||||
|
@ -327,7 +350,7 @@ diragain:
|
|||
*/
|
||||
brelse(bp);
|
||||
if (error == NFSERR_BAD_COOKIE) {
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
nfs_vinvalbuf(vp, 0, cred, p, 1);
|
||||
error = EINVAL;
|
||||
}
|
||||
|
@ -358,7 +381,7 @@ diragain:
|
|||
* the server).
|
||||
*/
|
||||
if ((caddr_t)dp >= edp || (caddr_t)dp + dp->d_reclen > edp ||
|
||||
(en > 0 && NFS_GETCOOKIE(pdp) != uio->uio_offset)) {
|
||||
(en > 0 && NFS_GETCOOKIE(pdp) != ndp->dc_cookie)) {
|
||||
#ifdef DEBUG
|
||||
printf("invalid cache: %p %p %p len %u off %lx %lx\n",
|
||||
pdp, dp, edp, dp->d_reclen,
|
||||
|
@ -366,7 +389,7 @@ diragain:
|
|||
(unsigned long)NFS_GETCOOKIE(pdp));
|
||||
#endif
|
||||
brelse(bp);
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
nfs_vinvalbuf(vp, 0, cred, p, 0);
|
||||
goto diragain;
|
||||
}
|
||||
|
@ -400,9 +423,14 @@ diragain:
|
|||
*/
|
||||
|
||||
while ((caddr_t)dp < ep && (caddr_t)dp + dp->d_reclen <= ep) {
|
||||
if (cflag & NFSBIO_CACHECOOKIES)
|
||||
nfs_lookdircache(vp, NFS_GETCOOKIE(pdp), enn,
|
||||
bp->b_lblkno, 1);
|
||||
if (cflag & NFSBIO_CACHECOOKIES) {
|
||||
nndp = nfs_enterdircache(vp, NFS_GETCOOKIE(pdp),
|
||||
ndp->dc_blkcookie, enn, bp->b_lblkno);
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
|
||||
NFS_STASHCOOKIE32(pdp,
|
||||
nndp->dc_cookie32);
|
||||
}
|
||||
}
|
||||
pdp = dp;
|
||||
dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
|
||||
enn++;
|
||||
|
@ -417,10 +445,27 @@ diragain:
|
|||
|
||||
if ((on + n) < bp->b_validend) {
|
||||
curoff = NFS_GETCOOKIE(pdp);
|
||||
nfs_lookdircache(vp, curoff, enn, bp->b_lblkno, 1);
|
||||
nndp = nfs_enterdircache(vp, curoff, ndp->dc_blkcookie,
|
||||
enn, bp->b_lblkno);
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
|
||||
NFS_STASHCOOKIE32(pdp, nndp->dc_cookie32);
|
||||
curoff = nndp->dc_cookie32;
|
||||
}
|
||||
} else
|
||||
curoff = bp->b_dcookie;
|
||||
|
||||
/*
|
||||
* Always cache the entry for the next block,
|
||||
* so that readaheads can use it.
|
||||
*/
|
||||
nndp = nfs_enterdircache(vp, bp->b_dcookie, bp->b_dcookie, 0,0);
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
|
||||
if (curoff == bp->b_dcookie) {
|
||||
NFS_STASHCOOKIE32(pdp, nndp->dc_cookie32);
|
||||
curoff = nndp->dc_cookie32;
|
||||
}
|
||||
}
|
||||
|
||||
n = ((caddr_t)pdp + pdp->d_reclen) - (bp->b_data + on);
|
||||
|
||||
/*
|
||||
|
@ -430,12 +475,11 @@ diragain:
|
|||
*/
|
||||
if (nfs_numasync > 0 && nmp->nm_readahead > 0 &&
|
||||
np->n_direofoffset == 0 && !(np->n_flag & NQNFSNONCACHE)) {
|
||||
ndp = nfs_lookdircache(vp, bp->b_dcookie, 0, 0, 1);
|
||||
rabp = nfs_getcacheblk(vp, ndp->dc_blkno,
|
||||
rabp = nfs_getcacheblk(vp, nndp->dc_blkno,
|
||||
NFS_DIRBLKSIZ, p);
|
||||
if (rabp) {
|
||||
if ((rabp->b_flags & (B_DONE | B_DELWRI)) == 0) {
|
||||
rabp->b_dcookie = ndp->dc_cookie;
|
||||
rabp->b_dcookie = nndp->dc_cookie;
|
||||
rabp->b_flags |= (B_READ | B_ASYNC);
|
||||
if (nfs_asyncio(rabp, cred)) {
|
||||
rabp->b_flags |= B_INVAL;
|
||||
|
@ -973,7 +1017,7 @@ nfs_doio(bp, cr, p)
|
|||
NQNFS_CKINVALID(vp, np, ND_READ) &&
|
||||
np->n_lrev != np->n_brev) ||
|
||||
(!(nmp->nm_flag & NFSMNT_NQNFS) &&
|
||||
np->n_mtime != np->n_vattr.va_mtime.tv_sec))) {
|
||||
np->n_mtime != np->n_vattr->va_mtime.tv_sec))) {
|
||||
uprintf("Process killed due to text file modification\n");
|
||||
psignal(p, SIGKILL);
|
||||
p->p_holdcnt++;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_node.c,v 1.23 1997/10/10 01:53:19 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_node.c,v 1.24 1997/10/19 01:46:24 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -155,6 +155,9 @@ loop:
|
|||
np->n_fhp = &np->n_fh;
|
||||
bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
|
||||
np->n_fhsize = fhsize;
|
||||
MALLOC(np->n_vattr, struct vattr *, sizeof (struct vattr),
|
||||
M_NFSNODE, M_WAITOK);
|
||||
bzero(np->n_vattr, sizeof (struct vattr));
|
||||
lockmgr(&nfs_hashlock, LK_RELEASE, 0, p);
|
||||
*npp = np;
|
||||
return (0);
|
||||
|
@ -257,13 +260,14 @@ nfs_reclaim(v)
|
|||
* this nfs node.
|
||||
*/
|
||||
if (vp->v_type == VDIR && np->n_dircache) {
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 1);
|
||||
FREE(np->n_dircache, M_NFSDIROFF);
|
||||
}
|
||||
if (np->n_fhsize > NFS_SMALLFH) {
|
||||
FREE((caddr_t)np->n_fhp, M_NFSBIGFH);
|
||||
}
|
||||
|
||||
FREE(np->n_vattr, M_NFSNODE);
|
||||
cache_purge(vp);
|
||||
FREE(vp->v_data, M_NFSNODE);
|
||||
vp->v_data = (void *)0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_nqlease.c,v 1.21 1997/10/10 01:53:20 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_nqlease.c,v 1.22 1997/10/19 01:46:27 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -1068,7 +1068,7 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp, p)
|
|||
if (np->n_flag & (NMODIFIED | NQNFSEVICTED)) {
|
||||
if (np->n_flag & NQNFSEVICTED) {
|
||||
if (vp->v_type == VDIR)
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp,0);
|
||||
cache_purge(vp);
|
||||
(void) nfs_vinvalbuf(vp,
|
||||
V_SAVE, cred, p, 0);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_subs.c,v 1.48 1997/10/11 02:09:48 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_subs.c,v 1.49 1997/10/19 01:46:32 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -1120,6 +1120,41 @@ nfsm_strtmbuf(mb, bpos, cp, siz)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory caching routines. They work as follows:
|
||||
* - a cache is maintained per VDIR nfsnode.
|
||||
* - for each offset cookie that is exported to userspace, and can
|
||||
* thus be thrown back at us as an offset to VOP_READDIR, store
|
||||
* information in the cache.
|
||||
* - cached are:
|
||||
* - cookie itself
|
||||
* - blocknumber (essentially just a search key in the buffer cache)
|
||||
* - entry number in block.
|
||||
* - offset cookie of block in which this entry is stored
|
||||
* - 32 bit cookie if NFSMNT_XLATECOOKIE is used.
|
||||
* - entries are looked up in a hash table
|
||||
* - also maintained is an LRU list of entries, used to determine
|
||||
* which ones to delete if the cache grows too large.
|
||||
* - if 32 <-> 64 translation mode is requested for a filesystem,
|
||||
* the cache also functions as a translation table
|
||||
* - in the translation case, invalidating the cache does not mean
|
||||
* flushing it, but just marking entries as invalid, except for
|
||||
* the <64bit cookie, 32bitcookie> pair which is still valid, to
|
||||
* still be able to use the cache as a translation table.
|
||||
* - 32 bit cookies are uniquely created by combining the hash table
|
||||
* entry value, and one generation count per hash table entry,
|
||||
* incremented each time an entry is appended to the chain.
|
||||
* - the cache is invalidated each time a direcory is modified
|
||||
* - sanity checks are also done; if an entry in a block turns
|
||||
* out not to have a matching cookie, the cache is invalidated
|
||||
* and a new block starting from the wanted offset is fetched from
|
||||
* the server.
|
||||
* - directory entries as read from the server are extended to contain
|
||||
* the 64bit and, optionally, the 32bit cookies, for sanity checking
|
||||
* the cache and exporting them to userspace through the cookie
|
||||
* argument to VOP_READDIR.
|
||||
*/
|
||||
|
||||
u_long
|
||||
nfs_dirhash(off)
|
||||
off_t off;
|
||||
|
@ -1134,34 +1169,142 @@ nfs_dirhash(off)
|
|||
return sum;
|
||||
}
|
||||
|
||||
void
|
||||
nfs_initdircache(vp)
|
||||
struct vnode *vp;
|
||||
{
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
|
||||
|
||||
np->n_dircachesize = 0;
|
||||
np->n_dblkno = 1;
|
||||
np->n_dircache =
|
||||
hashinit(NFS_DIRHASHSIZ, M_NFSDIROFF, &nfsdirhashmask);
|
||||
TAILQ_INIT(&np->n_dirchain);
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
|
||||
MALLOC(np->n_dirgens, unsigned *,
|
||||
NFS_DIRHASHSIZ * sizeof (unsigned), M_NFSDIROFF,
|
||||
M_WAITOK);
|
||||
bzero((caddr_t)np->n_dirgens,
|
||||
NFS_DIRHASHSIZ * sizeof (unsigned));
|
||||
}
|
||||
}
|
||||
|
||||
static struct nfsdircache dzero = {0, 0, {0, 0}, {0, 0}, 0, 0, 0};
|
||||
|
||||
struct nfsdircache *
|
||||
nfs_lookdircache(vp, off, en, blkno, alloc)
|
||||
nfs_searchdircache(vp, off, do32, hashent)
|
||||
struct vnode *vp;
|
||||
off_t off;
|
||||
int do32;
|
||||
int *hashent;
|
||||
{
|
||||
struct nfsdirhashhead *ndhp;
|
||||
struct nfsdircache *ndp = NULL;
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
unsigned ent;
|
||||
|
||||
/*
|
||||
* Zero is always a valid cookie.
|
||||
*/
|
||||
if (off == 0)
|
||||
return &dzero;
|
||||
|
||||
/*
|
||||
* We use a 32bit cookie as search key, directly reconstruct
|
||||
* the hashentry. Else use the hashfunction.
|
||||
*/
|
||||
if (do32) {
|
||||
ent = (u_int32_t)off >> 24;
|
||||
if (ent >= NFS_DIRHASHSIZ)
|
||||
return NULL;
|
||||
ndhp = &np->n_dircache[ent];
|
||||
} else {
|
||||
ndhp = NFSDIRHASH(np, off);
|
||||
}
|
||||
|
||||
if (hashent)
|
||||
*hashent = (int)(ndhp - np->n_dircache);
|
||||
if (do32) {
|
||||
for (ndp = ndhp->lh_first; ndp; ndp = ndp->dc_hash.le_next) {
|
||||
if (ndp->dc_cookie32 == (u_int32_t)off) {
|
||||
/*
|
||||
* An invalidated entry will become the
|
||||
* start of a new block fetched from
|
||||
* the server.
|
||||
*/
|
||||
if (ndp->dc_blkno == -1) {
|
||||
ndp->dc_blkcookie = ndp->dc_cookie;
|
||||
ndp->dc_blkno = np->n_dblkno++;
|
||||
ndp->dc_entry = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ndp = ndhp->lh_first; ndp; ndp = ndp->dc_hash.le_next)
|
||||
if (ndp->dc_cookie == off)
|
||||
break;
|
||||
}
|
||||
return ndp;
|
||||
}
|
||||
|
||||
|
||||
struct nfsdircache *
|
||||
nfs_enterdircache(vp, off, blkoff, en, blkno)
|
||||
struct vnode *vp;
|
||||
off_t off, blkoff;
|
||||
daddr_t blkno;
|
||||
int en, alloc;
|
||||
int en;
|
||||
{
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
struct nfsdirhashhead *ndhp;
|
||||
struct nfsdircache *ndp, *first;
|
||||
struct nfsdircache *ndp = NULL, *first;
|
||||
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
|
||||
int hashent, gen, overwrite;
|
||||
|
||||
if (!np->n_dircache) {
|
||||
np->n_dircachesize = 0;
|
||||
np->n_dircache =
|
||||
hashinit(NFS_DIRHASHSIZ, M_NFSDIROFF, &nfsdirhashmask);
|
||||
TAILQ_INIT(&np->n_dirchain);
|
||||
if (!np->n_dircache)
|
||||
/*
|
||||
* XXX would like to do this in nfs_nget but vtype
|
||||
* isn't known at that time.
|
||||
*/
|
||||
nfs_initdircache(vp);
|
||||
|
||||
ndp = nfs_searchdircache(vp, off, 0, &hashent);
|
||||
|
||||
if (ndp && ndp->dc_blkno != -1) {
|
||||
/*
|
||||
* Overwriting an old entry. Check if it's the same.
|
||||
* If so, just return. If not, remove the old entry.
|
||||
*/
|
||||
if (ndp->dc_blkcookie == blkoff && ndp->dc_entry == en)
|
||||
return ndp;
|
||||
TAILQ_REMOVE(&np->n_dirchain, ndp, dc_chain);
|
||||
LIST_REMOVE(ndp, dc_hash);
|
||||
FREE(ndp, M_NFSDIROFF);
|
||||
ndp = 0;
|
||||
}
|
||||
|
||||
ndhp = NFSDIRHASH(np, off);
|
||||
for (ndp = ndhp->lh_first; ndp; ndp = ndp->dc_hash.le_next)
|
||||
if (ndp->dc_cookie == off)
|
||||
break;
|
||||
ndhp = &np->n_dircache[hashent];
|
||||
|
||||
if (!alloc || ndp)
|
||||
return ndp;
|
||||
MALLOC(ndp, struct nfsdircache *, sizeof (*ndp), M_NFSDIROFF, M_WAITOK);
|
||||
ndp->dc_cookie = off;
|
||||
if (!ndp) {
|
||||
MALLOC(ndp, struct nfsdircache *, sizeof (*ndp), M_NFSDIROFF,
|
||||
M_WAITOK);
|
||||
overwrite = 0;
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
|
||||
/*
|
||||
* We're allocating a new entry, so bump the
|
||||
* generation number.
|
||||
*/
|
||||
gen = ++np->n_dirgens[hashent];
|
||||
if (gen == 0) {
|
||||
np->n_dirgens[hashent]++;
|
||||
gen++;
|
||||
}
|
||||
ndp->dc_cookie32 = (hashent << 24) | (gen & 0xffffff);
|
||||
}
|
||||
} else
|
||||
overwrite = 1;
|
||||
|
||||
/*
|
||||
* If the entry number is 0, we are at the start of a new block, so
|
||||
|
@ -1171,8 +1314,14 @@ nfs_lookdircache(vp, off, en, blkno, alloc)
|
|||
ndp->dc_blkno = np->n_dblkno++;
|
||||
else
|
||||
ndp->dc_blkno = blkno;
|
||||
|
||||
ndp->dc_cookie = off;
|
||||
ndp->dc_blkcookie = blkoff;
|
||||
ndp->dc_entry = en;
|
||||
|
||||
if (overwrite)
|
||||
return ndp;
|
||||
|
||||
/*
|
||||
* If the maximum directory cookie cache size has been reached
|
||||
* for this node, take one off the front. The idea is that
|
||||
|
@ -1194,11 +1343,13 @@ nfs_lookdircache(vp, off, en, blkno, alloc)
|
|||
}
|
||||
|
||||
void
|
||||
nfs_invaldircache(vp)
|
||||
nfs_invaldircache(vp, forcefree)
|
||||
struct vnode *vp;
|
||||
int forcefree;
|
||||
{
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
struct nfsdircache *ndp = NULL;
|
||||
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (vp->v_type != VDIR)
|
||||
|
@ -1208,14 +1359,23 @@ nfs_invaldircache(vp)
|
|||
if (!np->n_dircache)
|
||||
return;
|
||||
|
||||
while ((ndp = np->n_dirchain.tqh_first)) {
|
||||
TAILQ_REMOVE(&np->n_dirchain, ndp, dc_chain);
|
||||
LIST_REMOVE(ndp, dc_hash);
|
||||
FREE(ndp, M_NFSDIROFF);
|
||||
if (!(nmp->nm_flag & NFSMNT_XLATECOOKIE) || forcefree) {
|
||||
while ((ndp = np->n_dirchain.tqh_first)) {
|
||||
TAILQ_REMOVE(&np->n_dirchain, ndp, dc_chain);
|
||||
LIST_REMOVE(ndp, dc_hash);
|
||||
FREE(ndp, M_NFSDIROFF);
|
||||
}
|
||||
np->n_dircachesize = 0;
|
||||
if (forcefree && np->n_dirgens) {
|
||||
FREE(np->n_dirgens, M_NFSDIROFF);
|
||||
}
|
||||
} else {
|
||||
for (ndp = np->n_dirchain.tqh_first; ndp;
|
||||
ndp = ndp->dc_chain.tqe_next)
|
||||
ndp->dc_blkno = -1;
|
||||
}
|
||||
|
||||
np->n_dblkno = 0;
|
||||
np->n_dircachesize = 0;
|
||||
np->n_dblkno = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1420,7 +1580,7 @@ nfs_loadattrcache(vpp, fp, vaper)
|
|||
}
|
||||
np->n_mtime = mtime.tv_sec;
|
||||
}
|
||||
vap = &np->n_vattr;
|
||||
vap = np->n_vattr;
|
||||
vap->va_type = vtyp;
|
||||
vap->va_mode = vmode & ALLPERMS;
|
||||
vap->va_rdev = (dev_t)rdev;
|
||||
|
@ -1507,7 +1667,7 @@ nfs_getattrcache(vp, vaper)
|
|||
return (ENOENT);
|
||||
}
|
||||
nfsstats.attrcache_hits++;
|
||||
vap = &np->n_vattr;
|
||||
vap = np->n_vattr;
|
||||
if (vap->va_size != np->n_size) {
|
||||
if (vap->va_type == VREG) {
|
||||
if (np->n_flag & NMODIFIED) {
|
||||
|
@ -1588,7 +1748,7 @@ nfs_cookieheuristic(vp, flagp, p, cred)
|
|||
if (dp->d_fileno != 0 && len >= dp->d_reclen) {
|
||||
if ((*cop >> 32) != 0 && (*cop & 0xffffffffLL) == 0) {
|
||||
*flagp |= NFSMNT_SWAPCOOKIE;
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
nfs_vinvalbuf(vp, 0, cred, p, 1);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_var.h,v 1.10 1997/10/10 01:53:28 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_var.h,v 1.11 1997/10/19 01:46:36 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
|
||||
|
@ -231,9 +231,10 @@ int nfsm_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *));
|
|||
int nfs_adv __P((struct mbuf **, caddr_t *, int, int));
|
||||
int nfsm_strtmbuf __P((struct mbuf **, char **, const char *, long));
|
||||
u_long nfs_dirhash __P((off_t));
|
||||
struct nfsdircache *nfs_lookdircache __P((struct vnode *, off_t, int, daddr_t,
|
||||
int));
|
||||
void nfs_invaldircache __P((struct vnode *));
|
||||
void nfs_initdircache __P((struct vnode *));
|
||||
struct nfsdircache *nfs_searchdircache __P((struct vnode *, off_t, int, int *));
|
||||
struct nfsdircache *nfs_enterdircache __P((struct vnode *, off_t, off_t, daddr_t, int));
|
||||
void nfs_invaldircache __P((struct vnode *, int));
|
||||
void nfs_init __P((void));
|
||||
int nfsm_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
|
||||
struct vattr *));
|
||||
|
@ -256,7 +257,6 @@ int nfsrv_setpublicfs __P((struct mount *, struct netexport *,
|
|||
struct export_args *));
|
||||
int nfs_ispublicfh __P((fhandle_t *));
|
||||
int netaddr_match __P((int, union nethostaddr *, struct mbuf *));
|
||||
void nfs_invaldircache __P((struct vnode *));
|
||||
void nfs_clearcommit __P((struct mount *));
|
||||
int nfsrv_errmap __P((struct nfsrv_descript *, int));
|
||||
void nfsrvw_sort __P((gid_t *, int));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_vfsops.c,v 1.65 1997/10/10 01:53:29 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_vfsops.c,v 1.66 1997/10/19 01:46:40 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
|
@ -471,6 +471,13 @@ nfs_decode_args(nmp, argp)
|
|||
if (argp->sotype == SOCK_STREAM)
|
||||
argp->flags &= ~NFSMNT_NOCONN;
|
||||
|
||||
/*
|
||||
* Cookie translation is not needed for v2, silently ignore it.
|
||||
*/
|
||||
if ((argp->flags & (NFSMNT_XLATECOOKIE|NFSMNT_NFSV3)) ==
|
||||
NFSMNT_XLATECOOKIE)
|
||||
argp->flags &= ~NFSMNT_XLATECOOKIE;
|
||||
|
||||
/* Re-bind if rsrvd port requested and wasn't on one */
|
||||
adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
|
||||
&& (argp->flags & NFSMNT_RESVPORT);
|
||||
|
@ -614,10 +621,12 @@ nfs_mount(mp, path, data, ndp, p)
|
|||
return (EIO);
|
||||
/*
|
||||
* When doing an update, we can't change from or to
|
||||
* v3 and/or nqnfs.
|
||||
* v3 and/or nqnfs, or change cookie translation
|
||||
*/
|
||||
args.flags = (args.flags & ~(NFSMNT_NFSV3|NFSMNT_NQNFS)) |
|
||||
(nmp->nm_flag & (NFSMNT_NFSV3|NFSMNT_NQNFS));
|
||||
args.flags = (args.flags &
|
||||
~(NFSMNT_NFSV3|NFSMNT_NQNFS|NFSMNT_XLATECOOKIE)) |
|
||||
(nmp->nm_flag &
|
||||
(NFSMNT_NFSV3|NFSMNT_NQNFS|NFSMNT_XLATECOOKIE));
|
||||
nfs_decode_args(nmp, &args);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_vnops.c,v 1.84 1997/10/17 00:00:41 christos Exp $ */
|
||||
/* $NetBSD: nfs_vnops.c,v 1.85 1997/10/19 01:46:47 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -433,7 +433,7 @@ nfs_open(v)
|
|||
(void) vnode_pager_uncache(vp);
|
||||
np->n_attrstamp = 0;
|
||||
if (vp->v_type == VDIR) {
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
np->n_direofoffset = 0;
|
||||
}
|
||||
error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p);
|
||||
|
@ -446,7 +446,7 @@ nfs_open(v)
|
|||
return (error);
|
||||
if (np->n_mtime != vattr.va_mtime.tv_sec) {
|
||||
if (vp->v_type == VDIR) {
|
||||
nfs_invaldircache(vp);
|
||||
nfs_invaldircache(vp, 0);
|
||||
np->n_direofoffset = 0;
|
||||
}
|
||||
if ((error = nfs_vinvalbuf(vp, V_SAVE,
|
||||
|
@ -642,7 +642,7 @@ nfs_setattr(v)
|
|||
return (error);
|
||||
}
|
||||
tsize = np->n_size;
|
||||
np->n_size = np->n_vattr.va_size = vap->va_size;
|
||||
np->n_size = np->n_vattr->va_size = vap->va_size;
|
||||
}
|
||||
} else if ((vap->va_mtime.tv_sec != VNOVAL ||
|
||||
vap->va_atime.tv_sec != VNOVAL) &&
|
||||
|
@ -652,7 +652,7 @@ nfs_setattr(v)
|
|||
return (error);
|
||||
error = nfs_setattrrpc(vp, vap, ap->a_cred, ap->a_p);
|
||||
if (error && vap->va_size != VNOVAL) {
|
||||
np->n_size = np->n_vattr.va_size = tsize;
|
||||
np->n_size = np->n_vattr->va_size = tsize;
|
||||
vnode_pager_setsize(vp, np->n_size);
|
||||
}
|
||||
return (error);
|
||||
|
@ -918,7 +918,7 @@ dorpc:
|
|||
cnp->cn_flags |= SAVENAME;
|
||||
if ((cnp->cn_flags & MAKEENTRY) &&
|
||||
(cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) {
|
||||
np->n_ctime = np->n_vattr.va_ctime.tv_sec;
|
||||
np->n_ctime = np->n_vattr->va_ctime.tv_sec;
|
||||
cache_enter(dvp, newvp, cnp);
|
||||
}
|
||||
*vpp = newvp;
|
||||
|
@ -928,7 +928,7 @@ dorpc:
|
|||
cnp->cn_nameiop != CREATE) {
|
||||
if (VTONFS(dvp)->n_nctime == 0)
|
||||
VTONFS(dvp)->n_nctime =
|
||||
VTONFS(dvp)->n_vattr.va_mtime.tv_sec;
|
||||
VTONFS(dvp)->n_vattr->va_mtime.tv_sec;
|
||||
cache_enter(dvp, NULL, cnp);
|
||||
}
|
||||
if (newvp != NULLVP)
|
||||
|
@ -1182,7 +1182,7 @@ nfs_writerpc(vp, uiop, cred, iomode, must_commit)
|
|||
} else
|
||||
nfsm_loadattr(vp, (struct vattr *)0);
|
||||
if (wccflag)
|
||||
VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec;
|
||||
VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr->va_mtime.tv_sec;
|
||||
m_freem(mrep);
|
||||
if (error)
|
||||
break;
|
||||
|
@ -1959,11 +1959,10 @@ nfs_readdir(v)
|
|||
int a_ncookies;
|
||||
} */ *ap = v;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct nfsnode *np = VTONFS(vp);
|
||||
register struct uio *uio = ap->a_uio;
|
||||
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
|
||||
char *base = uio->uio_iov->iov_base;
|
||||
int tresid, error;
|
||||
struct vattr vattr;
|
||||
size_t count, lost;
|
||||
|
||||
if (vp->v_type != VDIR)
|
||||
|
@ -1974,25 +1973,6 @@ nfs_readdir(v)
|
|||
if (count <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* First, check for hit on the EOF offset cache
|
||||
*/
|
||||
if (np->n_direofoffset != 0 && uio->uio_offset == np->n_direofoffset &&
|
||||
(np->n_flag & NMODIFIED) == 0) {
|
||||
if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) {
|
||||
if (NQNFS_CKCACHABLE(vp, ND_READ)) {
|
||||
nfsstats.direofcache_hits++;
|
||||
*ap->a_eofflag = 1;
|
||||
return (0);
|
||||
}
|
||||
} else if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp) == 0 &&
|
||||
np->n_mtime == vattr.va_mtime.tv_sec) {
|
||||
nfsstats.direofcache_hits++;
|
||||
*ap->a_eofflag = 1;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Call nfs_bioread() to do the real work.
|
||||
*/
|
||||
|
@ -2009,7 +1989,7 @@ nfs_readdir(v)
|
|||
|
||||
if (!error && ap->a_cookies) {
|
||||
struct dirent *dp;
|
||||
off_t *cookies = ap->a_cookies, *offp;
|
||||
off_t *cookies = ap->a_cookies;
|
||||
int ncookies = ap->a_ncookies;
|
||||
|
||||
/*
|
||||
|
@ -2023,9 +2003,10 @@ nfs_readdir(v)
|
|||
dp = (struct dirent *) base;
|
||||
if (dp->d_reclen == 0)
|
||||
break;
|
||||
offp = (off_t *)((caddr_t)dp + dp->d_reclen -
|
||||
sizeof (off_t));
|
||||
*(cookies++) = NFS_GETCOOKIE(dp);
|
||||
if (nmp->nm_flag & NFSMNT_XLATECOOKIE)
|
||||
*(cookies++) = (off_t)NFS_GETCOOKIE32(dp);
|
||||
else
|
||||
*(cookies++) = NFS_GETCOOKIE(dp);
|
||||
base += dp->d_reclen;
|
||||
}
|
||||
uio->uio_resid += (uio->uio_iov->iov_base - base);
|
||||
|
@ -2059,7 +2040,7 @@ nfs_readdirrpc(vp, uiop, cred)
|
|||
struct nfsnode *dnp = VTONFS(vp);
|
||||
u_quad_t fileno;
|
||||
int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1;
|
||||
int attrflag;
|
||||
int attrflag, nrpcs = 0;
|
||||
int v3 = NFS_ISV3(vp);
|
||||
nfsquad_t cookie;
|
||||
|
||||
|
@ -2078,6 +2059,16 @@ nfs_readdirrpc(vp, uiop, cred)
|
|||
* The stopping criteria is EOF or buffer full.
|
||||
*/
|
||||
while (more_dirs && bigenough) {
|
||||
/*
|
||||
* Heuristic: don't bother to do another RPC to further
|
||||
* fill up this block if there is not much room left. (< 50%
|
||||
* of the readdir RPC size). This wastes some buffer space
|
||||
* but can save up to 50% in RPC calls.
|
||||
*/
|
||||
if (nrpcs > 0 && uiop->uio_resid < (nmp->nm_readdirsize / 2)) {
|
||||
bigenough = 0;
|
||||
break;
|
||||
}
|
||||
nfsstats.rpccnt[NFSPROC_READDIR]++;
|
||||
nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) +
|
||||
NFSX_READDIR(v3));
|
||||
|
@ -2099,6 +2090,7 @@ nfs_readdirrpc(vp, uiop, cred)
|
|||
}
|
||||
*tl = txdr_unsigned(nmp->nm_readdirsize);
|
||||
nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, cred);
|
||||
nrpcs++;
|
||||
if (v3) {
|
||||
nfsm_postop_attr(vp, attrflag);
|
||||
if (!error) {
|
||||
|
@ -2254,7 +2246,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
|
|||
nfsfh_t *fhp;
|
||||
u_quad_t fileno;
|
||||
int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
|
||||
int attrflag, fhsize;
|
||||
int attrflag, fhsize, nrpcs = 0;
|
||||
struct nfs_fattr fattr, *fp;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -2270,6 +2262,10 @@ nfs_readdirplusrpc(vp, uiop, cred)
|
|||
* The stopping criteria is EOF or buffer full.
|
||||
*/
|
||||
while (more_dirs && bigenough) {
|
||||
if (nrpcs > 0 && uiop->uio_resid < (nmp->nm_readdirsize / 2)) {
|
||||
bigenough = 0;
|
||||
break;
|
||||
}
|
||||
nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
|
||||
nfsm_reqhead(vp, NFSPROC_READDIRPLUS,
|
||||
NFSX_FH(1) + 6 * NFSX_UNSIGNED);
|
||||
|
@ -2291,6 +2287,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
|
|||
m_freem(mrep);
|
||||
goto nfsmout;
|
||||
}
|
||||
nrpcs++;
|
||||
nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
|
||||
dnp->n_cookieverf.nfsuquad[0] = *tl++;
|
||||
dnp->n_cookieverf.nfsuquad[1] = *tl++;
|
||||
|
@ -2383,7 +2380,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
|
|||
if (!error) {
|
||||
nfs_loadattrcache(&newvp, &fattr, 0);
|
||||
dp->d_type =
|
||||
IFTODT(VTTOIF(np->n_vattr.va_type));
|
||||
IFTODT(VTTOIF(np->n_vattr->va_type));
|
||||
ndp->ni_vp = newvp;
|
||||
cnp->cn_hash = 0;
|
||||
for (hcp = cnp->cn_nameptr, i = 1; i <= len;
|
||||
|
@ -2983,7 +2980,7 @@ nfs_print(v)
|
|||
register struct nfsnode *np = VTONFS(vp);
|
||||
|
||||
printf("tag VT_NFS, fileid %ld fsid 0x%lx",
|
||||
np->n_vattr.va_fileid, np->n_vattr.va_fsid);
|
||||
np->n_vattr->va_fileid, np->n_vattr->va_fsid);
|
||||
#ifdef FIFO
|
||||
if (vp->v_type == VFIFO)
|
||||
fifo_printinfo(vp);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfsnode.h,v 1.23 1997/10/16 23:59:34 christos Exp $ */
|
||||
/* $NetBSD: nfsnode.h,v 1.24 1997/10/19 01:46:51 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -78,11 +78,13 @@ LIST_HEAD(nfsdirhashhead, nfsdircache);
|
|||
TAILQ_HEAD(nfsdirchainhead, nfsdircache);
|
||||
|
||||
struct nfsdircache {
|
||||
LIST_ENTRY(nfsdircache) dc_hash;
|
||||
TAILQ_ENTRY(nfsdircache) dc_chain;
|
||||
off_t dc_cookie;
|
||||
daddr_t dc_blkno;
|
||||
int dc_entry;
|
||||
off_t dc_cookie; /* Own offset (key) */
|
||||
off_t dc_blkcookie; /* Offset of block we're in */
|
||||
LIST_ENTRY(nfsdircache) dc_hash; /* Hash chain */
|
||||
TAILQ_ENTRY(nfsdircache) dc_chain; /* Least recently entered chn */
|
||||
u_int32_t dc_cookie32; /* Key for 64<->32 xlate case */
|
||||
daddr_t dc_blkno; /* Number of block we're in */
|
||||
int dc_entry; /* Entry number within block */
|
||||
};
|
||||
|
||||
|
||||
|
@ -100,39 +102,40 @@ struct nfsdircache {
|
|||
* be well aligned and, therefore, tightly packed.
|
||||
*/
|
||||
struct nfsnode {
|
||||
LIST_ENTRY(nfsnode) n_hash; /* Hash chain */
|
||||
CIRCLEQ_ENTRY(nfsnode) n_timer; /* Nqnfs timer chain */
|
||||
u_quad_t n_size; /* Current size of file */
|
||||
u_quad_t n_brev; /* Modify rev when cached */
|
||||
u_quad_t n_lrev; /* Modify rev for lease */
|
||||
struct vattr n_vattr; /* Vnode attribute cache */
|
||||
time_t n_attrstamp; /* Attr. cache timestamp */
|
||||
time_t n_mtime; /* Prev modify time. */
|
||||
time_t n_ctime; /* Prev create time. */
|
||||
time_t n_nctime; /* Last neg cache entry (dir) */
|
||||
time_t n_expiry; /* Lease expiry time */
|
||||
nfsfh_t *n_fhp; /* NFS File Handle */
|
||||
struct vnode *n_vnode; /* associated vnode */
|
||||
struct lockf *n_lockf; /* Locking record of file */
|
||||
int n_error; /* Save write error value */
|
||||
union {
|
||||
struct timespec nf_atim; /* Special file times */
|
||||
nfsuint64 nd_cookieverf; /* Cookie verifier (dir only) */
|
||||
} n_un1;
|
||||
union {
|
||||
struct timespec nf_mtim;
|
||||
off_t nd_direof; /* Dir. EOF offset cache */
|
||||
} n_un2;
|
||||
union {
|
||||
struct timespec nf_atim; /* Special file times */
|
||||
nfsuint64 nd_cookieverf; /* Cookie verifier (dir only) */
|
||||
} n_un1;
|
||||
union {
|
||||
struct sillyrename *nf_silly; /* Ptr to silly rename struct */
|
||||
struct nfsdirhashhead *nd_dircache;
|
||||
} n_un3;
|
||||
LIST_ENTRY(nfsnode) n_hash; /* Hash chain */
|
||||
CIRCLEQ_ENTRY(nfsnode) n_timer; /* Nqnfs timer chain */
|
||||
struct nfsdirchainhead n_dirchain; /* Chain of dir cookies */
|
||||
nfsfh_t *n_fhp; /* NFS File Handle */
|
||||
struct vattr *n_vattr; /* Vnode attribute cache */
|
||||
struct vnode *n_vnode; /* associated vnode */
|
||||
struct lockf *n_lockf; /* Locking record of file */
|
||||
unsigned *n_dirgens; /* 32<->64bit xlate gen. no. */
|
||||
time_t n_attrstamp; /* Attr. cache timestamp */
|
||||
time_t n_mtime; /* Prev modify time. */
|
||||
time_t n_ctime; /* Prev create time. */
|
||||
time_t n_nctime; /* Last neg cache entry (dir) */
|
||||
time_t n_expiry; /* Lease expiry time */
|
||||
daddr_t n_dblkno; /* To keep faked dir blkno */
|
||||
unsigned n_dircachesize; /* Size of dir cookie cache */
|
||||
int n_error; /* Save write error value */
|
||||
short n_fhsize; /* size in bytes, of fh */
|
||||
short n_flag; /* Flag for locking.. */
|
||||
nfsfh_t n_fh; /* Small File Handle */
|
||||
daddr_t n_dblkno; /* To keep faked dir blkno */
|
||||
unsigned n_dircachesize; /* Size of dir cookie cache */
|
||||
struct nfsdirchainhead n_dirchain; /* Chain of dir cookies */
|
||||
};
|
||||
|
||||
#define n_atim n_un1.nf_atim
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfsproto.h,v 1.6 1997/10/17 08:10:22 fvdl Exp $ */
|
||||
/* $NetBSD: nfsproto.h,v 1.7 1997/10/19 01:46:54 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -252,7 +252,7 @@ typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5,
|
|||
* NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4.
|
||||
*/
|
||||
#ifndef NFS_SMALLFH
|
||||
#define NFS_SMALLFH 32
|
||||
#define NFS_SMALLFH 64
|
||||
#endif
|
||||
union nfsfh {
|
||||
fhandle_t fh_generic;
|
||||
|
|
Loading…
Reference in New Issue