summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2013-08-06 08:22:38 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2013-08-06 08:22:38 +0000
commita81c1d8411fd014a2c5dfff5dfc5c16ea68ac1b2 (patch)
tree955c6400b7ab9b5dea83cf004da4547695195cde /sys
parent52b25c22978760637c8252452fa8b5d38a9ae81e (diff)
Make it possible to have multiple clonable devices per major.
Diffstat (limited to 'sys')
-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