diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index a7efa3454ca0..7294d5f772a3 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -661,6 +661,7 @@ vfs_nmount(td, fsflags, fsoptions) mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO); TAILQ_INIT(&mp->mnt_nvnodelist); TAILQ_INIT(&mp->mnt_reservedvnlist); + mp->mnt_nvnodelistsize = 0; lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE); (void)vfs_busy(mp, LK_NOWAIT, 0, td); mp->mnt_op = vfsp->vfc_vfsops; @@ -1025,6 +1026,7 @@ vfs_mount(td, fstype, fspath, fsflags, fsdata) mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO); TAILQ_INIT(&mp->mnt_nvnodelist); TAILQ_INIT(&mp->mnt_reservedvnlist); + mp->mnt_nvnodelistsize = 0; lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE); (void)vfs_busy(mp, LK_NOWAIT, 0, td); mp->mnt_op = vfsp->vfc_vfsops; @@ -1390,6 +1392,7 @@ vfs_rootmountalloc(fstypename, devname, mpp) (void)vfs_busy(mp, LK_NOWAIT, 0, td); TAILQ_INIT(&mp->mnt_nvnodelist); TAILQ_INIT(&mp->mnt_reservedvnlist); + mp->mnt_nvnodelistsize = 0; mp->mnt_vfc = vfsp; mp->mnt_op = vfsp->vfc_vfsops; mp->mnt_flag = MNT_RDONLY; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 7441e19d2f6c..554b5e27a163 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -674,12 +674,13 @@ vattr_null(vap) * you set kern.maxvnodes to. Do not set kern.maxvnodes too low. */ static int -vlrureclaim(struct mount *mp, int count) +vlrureclaim(struct mount *mp) { struct vnode *vp; int done; int trigger; int usevnodes; + int count; /* * Calculate the trigger point, don't allow user @@ -695,6 +696,7 @@ vlrureclaim(struct mount *mp, int count) done = 0; mtx_lock(&mntvnode_mtx); + count = mp->mnt_nvnodelistsize / 10 + 1; while (count && (vp = TAILQ_FIRST(&mp->mnt_nvnodelist)) != NULL) { TAILQ_REMOVE(&mp->mnt_nvnodelist, vp, v_nmntvnodes); TAILQ_INSERT_TAIL(&mp->mnt_nvnodelist, vp, v_nmntvnodes); @@ -731,7 +733,7 @@ vnlru_proc(void) { struct mount *mp, *nmp; int s; - int done, take; + int done; struct proc *p = vnlruproc; struct thread *td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ @@ -754,16 +756,12 @@ vnlru_proc(void) mtx_unlock(&vnode_free_list_mtx); done = 0; mtx_lock(&mountlist_mtx); - take = 0; - TAILQ_FOREACH(mp, &mountlist, mnt_list) - take++; - take = desiredvnodes / (take * 10); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } - done += vlrureclaim(mp, take); + done += vlrureclaim(mp); mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp, td); @@ -1041,8 +1039,12 @@ insmntque(vp, mp) /* * Delete from old mount point vnode list, if on one. */ - if (vp->v_mount != NULL) + if (vp->v_mount != NULL) { + KASSERT(vp->v_mount->mnt_nvnodelistsize > 0, + ("bad mount point vnode list size")); TAILQ_REMOVE(&vp->v_mount->mnt_nvnodelist, vp, v_nmntvnodes); + vp->v_mount->mnt_nvnodelistsize--; + } /* * Insert into list of vnodes for the new mount point, if available. */ @@ -1051,6 +1053,7 @@ insmntque(vp, mp) return; } TAILQ_INSERT_TAIL(&mp->mnt_nvnodelist, vp, v_nmntvnodes); + mp->mnt_nvnodelistsize++; mtx_unlock(&mntvnode_mtx); } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 0d834e71e119..7c4c4715b58e 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -146,6 +146,7 @@ struct mount { struct netexport *mnt_export; /* export list */ struct label mnt_mntlabel; /* MAC label for the mount */ struct label mnt_fslabel; /* MAC label for the fs */ + int mnt_nvnodelistsize; /* # of vnodes on this mount */ }; #endif /* _KERNEL */