diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 62897158d295..08ba8f272713 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95 - * $Id: vfs_cache.c,v 1.30 1997/09/03 09:20:17 phk Exp $ + * $Id: vfs_cache.c,v 1.31 1997/09/04 08:24:44 phk Exp $ */ #include @@ -86,6 +86,26 @@ SYSCTL_INT(_debug, OID_AUTO, vfscache, CTLFLAG_RW, &doingcache, 0, ""); SYSCTL_INT(_debug, OID_AUTO, vnsize, CTLFLAG_RD, 0, sizeof(struct vnode), ""); SYSCTL_INT(_debug, OID_AUTO, ncsize, CTLFLAG_RD, 0, sizeof(struct namecache), ""); +/* + * The new name cache statistics + */ +SYSCTL_NODE(_vfs, CTL_VFS, cache, CTLFLAG_RW, 0, + "Name cache statistics"); +#define STATNODE(mode, name, var) \ + SYSCTL_INT(_vfs_cache, OID_AUTO, name, mode, var, 0, ""); +STATNODE(CTLFLAG_RD, numneg, &numneg); +STATNODE(CTLFLAG_RD, numcache, &numcache); +static u_long numcalls; STATNODE(CTLFLAG_RD, numcalls, &numcalls); +static u_long dothits; STATNODE(CTLFLAG_RD, dothits, &dothits); +static u_long dotdothits; STATNODE(CTLFLAG_RD, dotdothits, &dotdothits); +static u_long numchecks; STATNODE(CTLFLAG_RD, numchecks, &numchecks); +static u_long nummiss; STATNODE(CTLFLAG_RD, nummiss, &nummiss); +static u_long numposzaps; STATNODE(CTLFLAG_RD, numposzaps, &numposzaps); +static u_long numposhits; STATNODE(CTLFLAG_RD, numposhits, &numposhits); +static u_long numnegzaps; STATNODE(CTLFLAG_RD, numnegzaps, &numnegzaps); +static u_long numneghits; STATNODE(CTLFLAG_RD, numneghits, &numneghits); + + static void cache_zap __P((struct namecache *ncp)); /* @@ -143,12 +163,16 @@ cache_lookup(dvp, vpp, cnp) return (0); } + numcalls++; + if (cnp->cn_nameptr[0] == '.') { if (cnp->cn_namelen == 1) { *vpp = dvp; + dothits++; return (-1); } if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { + dotdothits++; if (dvp->v_dd->v_id != dvp->v_ddid || (cnp->cn_flags & MAKEENTRY) == 0) { dvp->v_ddid = 0; @@ -160,6 +184,7 @@ cache_lookup(dvp, vpp, cnp) } LIST_FOREACH(ncp, (NCHHASH(dvp, cnp)), nc_hash) { + numchecks++; if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && !bcmp(ncp->nc_name, cnp->cn_nameptr, (u_int)ncp->nc_nlen)) break; @@ -167,12 +192,14 @@ cache_lookup(dvp, vpp, cnp) /* We failed to find an entry */ if (ncp == 0) { + nummiss++; nchstats.ncs_miss++; return (0); } /* We don't want to have an entry, so dump it */ if ((cnp->cn_flags & MAKEENTRY) == 0) { + numposzaps++; nchstats.ncs_badhits++; cache_zap(ncp); return (0); @@ -180,6 +207,7 @@ cache_lookup(dvp, vpp, cnp) /* We found a "positive" match, return the vnode */ if (ncp->nc_vp) { + numposhits++; nchstats.ncs_goodhits++; *vpp = ncp->nc_vp; return (-1); @@ -187,11 +215,13 @@ cache_lookup(dvp, vpp, cnp) /* We found a negative match, and want to create it, so purge */ if (cnp->cn_nameiop == CREATE) { + numnegzaps++; nchstats.ncs_badhits++; cache_zap(ncp); return (0); } + numneghits++; /* * We found a "negative" match, ENOENT notifies client of this match. * The nc_vpid field records whether this is a whiteout. diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 810cc590f4d4..3f0a9da59d85 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.103 1997/09/14 02:49:06 peter Exp $ + * $Id: vfs_subr.c,v 1.104 1997/09/16 11:43:38 bde Exp $ */ /* @@ -95,6 +95,8 @@ int vttoif_tab[9] = { (bp)->b_vnbufs.le_next = NOLIST; \ } TAILQ_HEAD(freelst, vnode) vnode_free_list; /* vnode free list */ +static u_long wantfreevnodes = 0; +SYSCTL_INT(_debug, OID_AUTO, wantfreevnodes, CTLFLAG_RW, &wantfreevnodes, 0, ""); static u_long freevnodes = 0; SYSCTL_INT(_debug, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, ""); @@ -350,7 +352,11 @@ getnewvnode(tag, mp, vops, vpp) simple_lock(&vnode_free_list_slock); - if (freevnodes >= desiredvnodes) { + if (wantfreevnodes && freevnodes < wantfreevnodes) { + vp = NULL; + } else if (freevnodes <= desiredvnodes) { + vp = NULL; + } else { TAILQ_FOREACH(vp, &vnode_free_list, v_freelist) { if (!simple_lock_try(&vp->v_interlock)) continue; @@ -369,8 +375,6 @@ getnewvnode(tag, mp, vops, vpp) break; } } - } else { - vp = NULL; } if (vp) { diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 030136be0a0e..b8da0350a0ad 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.71 1997/09/16 08:05:09 phk Exp $ + * $Id: vfs_syscalls.c,v 1.72 1997/09/21 04:23:03 dyson Exp $ */ /* @@ -2770,6 +2770,18 @@ struct __getcwd_args { u_int buflen; }; #endif +#define STATNODE(mode, name, var) \ + SYSCTL_INT(_vfs_cache, OID_AUTO, name, mode, var, 0, ""); + +static int disablecwd; +SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, ""); + +static u_long numcwdcalls; STATNODE(CTLFLAG_RD, numcwdcalls, &numcwdcalls); +static u_long numcwdfail1; STATNODE(CTLFLAG_RD, numcwdfail1, &numcwdfail1); +static u_long numcwdfail2; STATNODE(CTLFLAG_RD, numcwdfail2, &numcwdfail2); +static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3); +static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4); +static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound); int __getcwd(p, uap, retval) struct proc *p; @@ -2782,6 +2794,8 @@ __getcwd(p, uap, retval) char *buf, *bp; int i, j, error; + if (disablecwd) + return (ENODEV); fdp = p->p_fd; j = 0; error = 0; @@ -2792,28 +2806,34 @@ __getcwd(p, uap, retval) buf = bp = malloc(uap->buflen, M_TEMP, M_WAITOK); bp += uap->buflen - 1; *bp = '\0'; + numcwdcalls++; for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) { if (vp->v_dd->v_id != vp->v_ddid) { + numcwdfail1++; free(buf, M_TEMP); return (ENOTDIR); } ncp = TAILQ_FIRST(&vp->v_cache_dst); if (!ncp) { + numcwdfail2++; free(buf, M_TEMP); return (ENOENT); } if (ncp->nc_dvp != vp->v_dd) { + numcwdfail3++; free(buf, M_TEMP); return (EBADF); } for (i=ncp->nc_nlen - 1; i >= 0; i--) { if (bp == buf) { + numcwdfail4++; free(buf, M_TEMP); return (ENOMEM); } *--bp = ncp->nc_name[i]; } if (bp == buf) { + numcwdfail4++; free(buf, M_TEMP); return (ENOMEM); } @@ -2825,11 +2845,13 @@ __getcwd(p, uap, retval) } if (!j) { if (bp == buf) { + numcwdfail4++; free(buf, M_TEMP); return (ENOMEM); } *--bp = '/'; } + numcwdfound++; error = copyout(bp, uap->buf, strlen(bp) + 1); free(buf, M_TEMP); return (error); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 810cc590f4d4..3f0a9da59d85 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.103 1997/09/14 02:49:06 peter Exp $ + * $Id: vfs_subr.c,v 1.104 1997/09/16 11:43:38 bde Exp $ */ /* @@ -95,6 +95,8 @@ int vttoif_tab[9] = { (bp)->b_vnbufs.le_next = NOLIST; \ } TAILQ_HEAD(freelst, vnode) vnode_free_list; /* vnode free list */ +static u_long wantfreevnodes = 0; +SYSCTL_INT(_debug, OID_AUTO, wantfreevnodes, CTLFLAG_RW, &wantfreevnodes, 0, ""); static u_long freevnodes = 0; SYSCTL_INT(_debug, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, ""); @@ -350,7 +352,11 @@ getnewvnode(tag, mp, vops, vpp) simple_lock(&vnode_free_list_slock); - if (freevnodes >= desiredvnodes) { + if (wantfreevnodes && freevnodes < wantfreevnodes) { + vp = NULL; + } else if (freevnodes <= desiredvnodes) { + vp = NULL; + } else { TAILQ_FOREACH(vp, &vnode_free_list, v_freelist) { if (!simple_lock_try(&vp->v_interlock)) continue; @@ -369,8 +375,6 @@ getnewvnode(tag, mp, vops, vpp) break; } } - } else { - vp = NULL; } if (vp) { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 030136be0a0e..b8da0350a0ad 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.71 1997/09/16 08:05:09 phk Exp $ + * $Id: vfs_syscalls.c,v 1.72 1997/09/21 04:23:03 dyson Exp $ */ /* @@ -2770,6 +2770,18 @@ struct __getcwd_args { u_int buflen; }; #endif +#define STATNODE(mode, name, var) \ + SYSCTL_INT(_vfs_cache, OID_AUTO, name, mode, var, 0, ""); + +static int disablecwd; +SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, ""); + +static u_long numcwdcalls; STATNODE(CTLFLAG_RD, numcwdcalls, &numcwdcalls); +static u_long numcwdfail1; STATNODE(CTLFLAG_RD, numcwdfail1, &numcwdfail1); +static u_long numcwdfail2; STATNODE(CTLFLAG_RD, numcwdfail2, &numcwdfail2); +static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3); +static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4); +static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound); int __getcwd(p, uap, retval) struct proc *p; @@ -2782,6 +2794,8 @@ __getcwd(p, uap, retval) char *buf, *bp; int i, j, error; + if (disablecwd) + return (ENODEV); fdp = p->p_fd; j = 0; error = 0; @@ -2792,28 +2806,34 @@ __getcwd(p, uap, retval) buf = bp = malloc(uap->buflen, M_TEMP, M_WAITOK); bp += uap->buflen - 1; *bp = '\0'; + numcwdcalls++; for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) { if (vp->v_dd->v_id != vp->v_ddid) { + numcwdfail1++; free(buf, M_TEMP); return (ENOTDIR); } ncp = TAILQ_FIRST(&vp->v_cache_dst); if (!ncp) { + numcwdfail2++; free(buf, M_TEMP); return (ENOENT); } if (ncp->nc_dvp != vp->v_dd) { + numcwdfail3++; free(buf, M_TEMP); return (EBADF); } for (i=ncp->nc_nlen - 1; i >= 0; i--) { if (bp == buf) { + numcwdfail4++; free(buf, M_TEMP); return (ENOMEM); } *--bp = ncp->nc_name[i]; } if (bp == buf) { + numcwdfail4++; free(buf, M_TEMP); return (ENOMEM); } @@ -2825,11 +2845,13 @@ __getcwd(p, uap, retval) } if (!j) { if (bp == buf) { + numcwdfail4++; free(buf, M_TEMP); return (ENOMEM); } *--bp = '/'; } + numcwdfound++; error = copyout(bp, uap->buf, strlen(bp) + 1); free(buf, M_TEMP); return (error);