summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2013-08-06 08:22:37 +0000
committerkettenis <kettenis@openbsd.org>2013-08-06 08:22:37 +0000
commit8ee7e372d768100fd5261a28f21d57ad9fa08738 (patch)
tree2c180963e051d8b73c5977a6d103e71c5553d2b9
parentThe atomic_setbits_int() and atomic_clearbits_int() functions touch the (diff)
downloadwireguard-openbsd-8ee7e372d768100fd5261a28f21d57ad9fa08738.tar.xz
wireguard-openbsd-8ee7e372d768100fd5261a28f21d57ad9fa08738.zip
Make it possible to have multiple clonable devices per major.
-rw-r--r--sys/kern/spec_vnops.c10
-rw-r--r--sys/sys/specdev.h8
2 files changed, 14 insertions, 4 deletions
diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c
index 49d301de241..20ce5f2da03 100644
--- a/sys/kern/spec_vnops.c
+++ b/sys/kern/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spec_vnops.c,v 1.75 2013/07/29 18:51:42 kettenis Exp $ */
+/* $OpenBSD: spec_vnops.c,v 1.76 2013/08/06 08:22:37 kettenis Exp $ */
/* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */
/*
@@ -691,6 +691,9 @@ spec_open_clone(struct vop_open_args *ap)
DNPRINTF("cloning vnode\n");
+ if (minor(vp->v_rdev) >= (1 << CLONE_SHIFT))
+ return (ENXIO);
+
for (i = 1; i < sizeof(vp->v_specbitmap) * NBBY; i++)
if (isclr(vp->v_specbitmap, i)) {
setbit(vp->v_specbitmap, i);
@@ -700,7 +703,8 @@ spec_open_clone(struct vop_open_args *ap)
if (i == sizeof(vp->v_specbitmap) * NBBY)
return (EBUSY); /* too many open instances */
- error = cdevvp(makedev(major(vp->v_rdev), i), &cvp);
+ error = cdevvp(makedev(major(vp->v_rdev),
+ (i << CLONE_SHIFT) | minor(vp->v_rdev)), &cvp);
if (error) {
clrbit(vp->v_specbitmap, i);
return (error); /* out of vnodes */
@@ -746,7 +750,7 @@ spec_close_clone(struct vop_close_args *ap)
return (error); /* device close failed */
pvp = vp->v_specparent; /* get parent device */
- clrbit(pvp->v_specbitmap, minor(vp->v_rdev));
+ clrbit(pvp->v_specbitmap, minor(vp->v_rdev) >> CLONE_SHIFT);
vrele(pvp);
return (0); /* clone closed */
diff --git a/sys/sys/specdev.h b/sys/sys/specdev.h
index 4de99ce4ff6..1d21e83530d 100644
--- a/sys/sys/specdev.h
+++ b/sys/sys/specdev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specdev.h,v 1.32 2013/06/11 16:42:18 deraadt Exp $ */
+/* $OpenBSD: specdev.h,v 1.33 2013/08/06 08:22:37 kettenis Exp $ */
/* $NetBSD: specdev.h,v 1.12 1996/02/13 13:13:01 mycroft Exp $ */
/*
@@ -67,6 +67,12 @@ struct cloneinfo {
#define v_specbitmap v_specinfo->si_ci.ci_bitmap
/*
+ * We use the upper 16 bits of the minor to record the clone instance.
+ * This gives us 8 bits for encoding the real minor number.
+ */
+#define CLONE_SHIFT 8
+
+/*
* Special device management
*/
#define SPECHSZ 64