summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Natano <natano@cvs.openbsd.org>2016-03-31 20:00:18 +0000
committerMartin Natano <natano@cvs.openbsd.org>2016-03-31 20:00:18 +0000
commitc72e9d7421d8ee6b6c87822906d495370391a755 (patch)
tree3e6de9e4bf936cbfb872f252e188f4bf11e6cd3f
parent78aedf5c9630dfcd363c256403311da51e199b66 (diff)
Increase size of the clone bitmap. A limit of only 64 device clones
turned out to be too low for the upcoming work on cloning bpf. The new limit is 1024 device clones. As part of the size increase, the bitmap has been changed to be allocated separately to avoid bloating all device nodes, as suggested by guenther, millert and deraadt. ok millert mikeb
-rw-r--r--sys/kern/spec_vnops.c7
-rw-r--r--sys/kern/vfs_subr.c15
-rw-r--r--sys/sys/specdev.h5
3 files changed, 20 insertions, 7 deletions
diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c
index 265a558d4b5..9a5e9e0f2b0 100644
--- a/sys/kern/spec_vnops.c
+++ b/sys/kern/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spec_vnops.c,v 1.86 2016/03/19 12:04:15 natano Exp $ */
+/* $OpenBSD: spec_vnops.c,v 1.87 2016/03/31 20:00:17 natano Exp $ */
/* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */
/*
@@ -707,13 +707,14 @@ spec_open_clone(struct vop_open_args *ap)
if (minor(vp->v_rdev) >= (1 << CLONE_SHIFT))
return (ENXIO);
- for (i = 1; i < sizeof(vp->v_specbitmap) * NBBY; i++)
+ for (i = 1; i < CLONE_MAP_SZ * NBBY; i++) {
if (isclr(vp->v_specbitmap, i)) {
setbit(vp->v_specbitmap, i);
break;
}
+ }
- if (i == sizeof(vp->v_specbitmap) * NBBY)
+ if (i == CLONE_MAP_SZ * NBBY)
return (EBUSY); /* too many open instances */
error = cdevvp(makedev(major(vp->v_rdev),
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 966e8977f9c..fb4e22da8d9 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.240 2016/03/19 12:04:15 natano Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.241 2016/03/31 20:00:17 natano Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -555,7 +555,13 @@ loop:
nvp->v_specnext = *vpp;
nvp->v_specmountpoint = NULL;
nvp->v_speclockf = NULL;
- memset(nvp->v_specbitmap, 0, sizeof(nvp->v_specbitmap));
+ nvp->v_specbitmap = NULL;
+ if (nvp_rdev == VCHR &&
+ (cdevsw[major(nvp_rdev)].d_flags & D_CLONE) &&
+ minor(nvp_rdev) >> CLONE_SHIFT == 0) {
+ nvp->v_specbitmap = malloc(CLONE_MAP_SZ, M_VNODE,
+ M_WAITOK | M_ZERO);
+ }
*vpp = nvp;
if (vp != NULLVP) {
nvp->v_flag |= VALIASED;
@@ -1093,6 +1099,11 @@ vgonel(struct vnode *vp, struct proc *p)
vx->v_flag &= ~VALIASED;
vp->v_flag &= ~VALIASED;
}
+ if (vp->v_rdev == VCHR &&
+ (cdevsw[major(vp->v_rdev)].d_flags & D_CLONE) &&
+ minor(vp->v_rdev) >> CLONE_SHIFT == 0) {
+ free(vp->v_specbitmap, M_VNODE, CLONE_MAP_SZ);
+ }
free(vp->v_specinfo, M_VNODE, sizeof(struct specinfo));
vp->v_specinfo = NULL;
}
diff --git a/sys/sys/specdev.h b/sys/sys/specdev.h
index 092b903808f..b550c720497 100644
--- a/sys/sys/specdev.h
+++ b/sys/sys/specdev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specdev.h,v 1.34 2013/11/02 00:16:31 deraadt Exp $ */
+/* $OpenBSD: specdev.h,v 1.35 2016/03/31 20:00:17 natano Exp $ */
/* $NetBSD: specdev.h,v 1.12 1996/02/13 13:13:01 mycroft Exp $ */
/*
@@ -46,7 +46,7 @@ struct specinfo {
daddr_t si_lastr;
union {
struct vnode *ci_parent; /* pointer back to parent device */
- u_int8_t ci_bitmap[8]; /* bitmap of devices cloned off us */
+ u_int8_t *ci_bitmap; /* bitmap of devices cloned off us */
} si_ci;
};
@@ -71,6 +71,7 @@ struct cloneinfo {
* This gives us 8 bits for encoding the real minor number.
*/
#define CLONE_SHIFT 8
+#define CLONE_MAP_SZ 128
/*
* Special device management