Index: fs/devfs/devfs_vfsops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/fs/devfs/devfs_vfsops.c,v retrieving revision 1.52 diff -u -p -r1.52 devfs_vfsops.c --- fs/devfs/devfs_vfsops.c 26 Sep 2006 04:12:45 -0000 1.52 +++ fs/devfs/devfs_vfsops.c 1 May 2007 00:16:41 -0000 @@ -185,4 +185,4 @@ static struct vfsops devfs_vfsops = { .vfs_unmount = devfs_unmount, }; -VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC); +VFS_SET(devfs_vfsops, devfs, sizeof(struct devfs_dirent), VFCF_SYNTHETIC); Index: fs/nullfs/null_vfsops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/fs/nullfs/null_vfsops.c,v retrieving revision 1.81 diff -u -p -r1.81 null_vfsops.c --- fs/nullfs/null_vfsops.c 15 Feb 2007 22:08:32 -0000 1.81 +++ fs/nullfs/null_vfsops.c 4 May 2007 17:32:06 -0000 @@ -371,4 +371,4 @@ static struct vfsops null_vfsops = { .vfs_vget = nullfs_vget, }; -VFS_SET(null_vfsops, nullfs, VFCF_LOOPBACK); +VFS_SET(null_vfsops, nullfs, sizeof(struct null_node), VFCF_LOOPBACK); Index: fs/unionfs/union_vfsops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/fs/unionfs/union_vfsops.c,v retrieving revision 1.82 diff -u -p -r1.82 union_vfsops.c --- fs/unionfs/union_vfsops.c 15 Feb 2007 22:08:33 -0000 1.82 +++ fs/unionfs/union_vfsops.c 4 May 2007 17:33:23 -0000 @@ -537,4 +537,4 @@ static struct vfsops unionfs_vfsops = { .vfs_vget = unionfs_vget, }; -VFS_SET(unionfs_vfsops, unionfs, VFCF_LOOPBACK); +VFS_SET(unionfs_vfsops, unionfs, sizeof(struct unionfs_node), VFCF_LOOPBACK); Index: kern/vfs_subr.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/kern/vfs_subr.c,v retrieving revision 1.700 diff -u -p -r1.700 vfs_subr.c --- kern/vfs_subr.c 13 Apr 2007 23:54:22 -0000 1.700 +++ kern/vfs_subr.c 4 May 2007 17:42:43 -0000 @@ -263,7 +263,7 @@ static enum { SYNCER_RUNNING, SYNCER_SHU * XXX desiredvnodes is historical cruft and should not exist. */ int desiredvnodes; -SYSCTL_INT(_kern, KERN_MAXVNODES, maxvnodes, CTLFLAG_RW, +SYSCTL_INT(_kern, KERN_MAXVNODES, maxvnodes, CTLFLAG_RD, &desiredvnodes, 0, "Maximum number of vnodes"); SYSCTL_INT(_kern, OID_AUTO, minvnodes, CTLFLAG_RW, &wantfreevnodes, 0, "Minimum number of vnodes (legacy)"); @@ -279,12 +279,18 @@ SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhe #define VSHOULDFREE(vp) (!((vp)->v_iflag & VI_FREE) && !(vp)->v_holdcnt) #define VSHOULDBUSY(vp) (((vp)->v_iflag & VI_FREE) && (vp)->v_holdcnt) +/* Total amount of memory used for vnodes. */ +static u_long vnodes_size; +SYSCTL_ULONG(_vfs, OID_AUTO, vnodes_size, CTLFLAG_RD, &vnodes_size, 0, ""); +/* Memory limit for vnodes. */ +static u_long vnodes_size_limit; +SYSCTL_ULONG(_vfs, OID_AUTO, vnodes_size_limit, CTLFLAG_RW, &vnodes_size_limit, 0, ""); /* * Initialize the vnode management data structures. */ #ifndef MAXVNODES_MAX -#define MAXVNODES_MAX 100000 +#define MAXVNODES_MAX 500000 #endif static void vntblinit(void *dummy __unused) @@ -305,6 +311,8 @@ vntblinit(void *dummy __unused) desiredvnodes, MAXVNODES_MAX); desiredvnodes = MAXVNODES_MAX; } + vnodes_size_limit = desiredvnodes * (sizeof(struct vm_object) + + sizeof(struct vnode)); wantfreevnodes = desiredvnodes / 4; mtx_init(&mntid_mtx, "mntid", NULL, MTX_DEF); TAILQ_INIT(&vnode_free_list); @@ -886,6 +894,13 @@ getnewvnode(const char *tag, struct moun struct bufobj *bo; mtx_lock(&vnode_free_list_mtx); + if (vnodes_size >= vnodes_size_limit) + desiredvnodes = numvnodes - 1; + else { + desiredvnodes = numvnodes + (vnodes_size_limit - vnodes_size) / + (sizeof(struct vnode) + sizeof(struct vm_object)); + } + wantfreevnodes = desiredvnodes / 4; /* * Lend our context to reclaim vnodes if they've exceeded the max. */ @@ -983,6 +998,7 @@ delmntque(struct vnode *vp) mp = vp->v_mount; if (mp == NULL) return; + atomic_add_long(&vnodes_size, -(mp->mnt_vfc->vfc_vsize + sizeof(struct vnode) + sizeof(struct vm_object))); MNT_ILOCK(mp); vp->v_mount = NULL; VNASSERT(mp->mnt_nvnodelistsize > 0, vp, @@ -1028,6 +1044,7 @@ insmntque1(struct vnode *vp, struct moun dtr(vp, dtr_arg); return (EBUSY); } + atomic_add_long(&vnodes_size, mp->mnt_vfc->vfc_vsize + sizeof(struct vnode) + sizeof(struct vm_object)); vp->v_mount = mp; MNT_REF(mp); TAILQ_INSERT_TAIL(&mp->mnt_nvnodelist, vp, v_nmntvnodes); Index: nfs4client/nfs4_vfsops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/nfs4client/nfs4_vfsops.c,v retrieving revision 1.27 diff -u -p -r1.27 nfs4_vfsops.c --- nfs4client/nfs4_vfsops.c 25 Jan 2007 14:18:40 -0000 1.27 +++ nfs4client/nfs4_vfsops.c 1 May 2007 00:17:48 -0000 @@ -140,7 +140,7 @@ static struct vfsops nfs4_vfsops = { .vfs_uninit = nfs4_uninit, .vfs_unmount = nfs4_unmount, }; -VFS_SET(nfs4_vfsops, nfs4, VFCF_NETWORK); +VFS_SET(nfs4_vfsops, nfs4, sizeof(struct nfsnode), VFCF_NETWORK); static struct nfs_rpcops nfs4_rpcops = { nfs4_readrpc, Index: nfsclient/nfs_vfsops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/nfsclient/nfs_vfsops.c,v retrieving revision 1.192 diff -u -p -r1.192 nfs_vfsops.c --- nfsclient/nfs_vfsops.c 23 Mar 2007 08:52:36 -0000 1.192 +++ nfsclient/nfs_vfsops.c 1 May 2007 19:37:19 -0000 @@ -132,7 +132,7 @@ static struct vfsops nfs_vfsops = { .vfs_unmount = nfs_unmount, .vfs_sysctl = nfs_sysctl, }; -VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK); +VFS_SET(nfs_vfsops, nfs, sizeof(struct nfsnode), VFCF_NETWORK); /* So that loader and kldload(2) can find us, wherever we are.. */ MODULE_VERSION(nfs, 1); Index: sys/mount.h =================================================================== RCS file: /zoo/pjd/repo/src/sys/sys/mount.h,v retrieving revision 1.226 diff -u -p -r1.226 mount.h --- sys/mount.h 22 Apr 2007 16:18:10 -0000 1.226 +++ sys/mount.h 1 May 2007 00:22:31 -0000 @@ -391,6 +391,7 @@ struct vfsconf { struct vfsops *vfc_vfsops; /* filesystem operations vector */ int vfc_typenum; /* historic filesystem type number */ int vfc_refcount; /* number mounted of this type */ + size_t vfc_vsize; /* v_data size */ int vfc_flags; /* permanent flags */ struct vfsoptdecl *vfc_opts; /* mount options */ TAILQ_ENTRY(vfsconf) vfc_list; /* list of vfscons */ @@ -624,12 +625,13 @@ extern int mpsafe_vfs; #define VFS_VERSION_00 0x19660120 #define VFS_VERSION VFS_VERSION_00 -#define VFS_SET(vfsops, fsname, flags) \ +#define VFS_SET(vfsops, fsname, vsize, flags) \ static struct vfsconf fsname ## _vfsconf = { \ .vfc_version = VFS_VERSION, \ .vfc_name = #fsname, \ .vfc_vfsops = &vfsops, \ .vfc_typenum = -1, \ + .vfc_vsize = vsize, \ .vfc_flags = flags, \ }; \ static moduledata_t fsname ## _mod = { \ Index: ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.329 diff -u -p -r1.329 ffs_vfsops.c --- ufs/ffs/ffs_vfsops.c 4 Apr 2007 07:29:53 -0000 1.329 +++ ufs/ffs/ffs_vfsops.c 1 May 2007 00:07:08 -0000 @@ -104,7 +104,7 @@ static struct vfsops ufs_vfsops = { .vfs_vget = ffs_vget, }; -VFS_SET(ufs_vfsops, ufs, 0); +VFS_SET(ufs_vfsops, ufs, sizeof(struct inode), 0); MODULE_VERSION(ufs, 1); static b_strategy_t ffs_geom_strategy;