summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_mount.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 61aafb3..117df18 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/systm.h>
#include <sys/vnode.h>
+#include <vm/uma.h>
#include <geom/geom.h>
@@ -91,6 +92,7 @@ SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");
MALLOC_DEFINE(M_VNODE_MARKER, "vnodemarker", "vnode marker");
+static uma_zone_t mount_zone;
/* List of mounted filesystems. */
struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist);
@@ -423,6 +425,27 @@ vfs_rel(struct mount *mp)
MNT_IUNLOCK(mp);
}
+static int
+mount_init(void *mem, int size, int flags)
+{
+ struct mount *mp;
+
+ mp = (struct mount *)mem;
+ mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF);
+ lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+ return (0);
+}
+
+static void
+mount_fini(void *mem, int size)
+{
+ struct mount *mp;
+
+ mp = (struct mount *)mem;
+ lockdestroy(&mp->mnt_lock);
+ mtx_destroy(&mp->mnt_mtx);
+}
+
/*
* Allocate and initialize the mount point struct.
*/
@@ -432,13 +455,13 @@ vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp,
{
struct mount *mp;
- mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
+ mp = uma_zalloc(mount_zone, M_WAITOK);
+ bzero(&mp->mnt_startzero,
+ __rangeof(struct mount, mnt_startzero, mnt_endzero));
TAILQ_INIT(&mp->mnt_nvnodelist);
mp->mnt_nvnodelistsize = 0;
- mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF);
- lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
- (void) vfs_busy(mp, LK_NOWAIT, 0, td);
mp->mnt_ref = 0;
+ (void) vfs_busy(mp, LK_NOWAIT, 0, td);
mp->mnt_op = vfsp->vfc_vfsops;
mp->mnt_vfc = vfsp;
vfsp->vfc_refcount++; /* XXX Unlocked */
@@ -466,7 +489,7 @@ vfs_mount_destroy(struct mount *mp, struct thread *td)
{
int i;
- vfs_unbusy(mp, td);
+ lockmgr(&mp->mnt_lock, LK_RELEASE, NULL, td);
MNT_ILOCK(mp);
for (i = 0; mp->mnt_ref && i < 3; i++)
msleep(mp, MNT_MTX(mp), PVFS, "mntref", hz);
@@ -512,7 +535,6 @@ vfs_mount_destroy(struct mount *mp, struct thread *td)
mp->mnt_vfc->vfc_refcount--;
if (!TAILQ_EMPTY(&mp->mnt_nvnodelist))
panic("unmount: dangling vnode");
- lockdestroy(&mp->mnt_lock);
MNT_ILOCK(mp);
if (mp->mnt_kern_flag & MNTK_MWAIT)
wakeup(mp);
@@ -526,14 +548,13 @@ vfs_mount_destroy(struct mount *mp, struct thread *td)
mp->mnt_nvnodelistsize = -1000;
mp->mnt_secondary_writes = -1000;
MNT_IUNLOCK(mp);
- mtx_destroy(&mp->mnt_mtx);
#ifdef MAC
mac_destroy_mount(mp);
#endif
if (mp->mnt_opt != NULL)
vfs_freeopts(mp->mnt_opt);
crfree(mp->mnt_cred);
- free(mp, M_MOUNT);
+ uma_zfree(mount_zone, mp);
}
static int
@@ -1375,6 +1396,9 @@ vfs_mountroot(void)
root_mount_wait();
+ mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount),
+ NULL, NULL, mount_init, mount_fini,
+ UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
devfs_first();
/*
OpenPOWER on IntegriCloud