diff options
author | Garrett D'Amore <Garrett.Damore@Sun.COM> | 2009-07-13 23:43:45 -0700 |
---|---|---|
committer | Garrett D'Amore <Garrett.Damore@Sun.COM> | 2009-07-13 23:43:45 -0700 |
commit | 349dcea37d1dc6e491c49c864c5e3773a4e3cae6 (patch) | |
tree | 4eebdc20eec12c6dcffdb2ee9a2694b75b918d5a /usr | |
parent | f0109389f635b59e47ad74e20059ea4283d73103 (diff) | |
download | illumos-gate-349dcea37d1dc6e491c49c864c5e3773a4e3cae6.tar.gz |
PSARC/2009/380 STREAMS and Character Device Coexistence
6858144 implement STREAMS/character device coexistence (PSARC 2009/380)
Diffstat (limited to 'usr')
-rw-r--r-- | usr/src/uts/common/fs/specfs/specsubr.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/fs/specfs/specvnops.c | 40 | ||||
-rw-r--r-- | usr/src/uts/common/os/driver_lyr.c | 10 |
3 files changed, 33 insertions, 25 deletions
diff --git a/usr/src/uts/common/fs/specfs/specsubr.c b/usr/src/uts/common/fs/specfs/specsubr.c index 9ae689c696..c43b4bd921 100644 --- a/usr/src/uts/common/fs/specfs/specsubr.c +++ b/usr/src/uts/common/fs/specfs/specsubr.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,8 +37,6 @@ */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/t_lock.h> #include <sys/param.h> @@ -740,7 +738,7 @@ spec_maxoffset(struct vnode *vp) struct snode *sp = VTOS(vp); struct snode *csp = VTOS(sp->s_commonvp); - if (STREAMSTAB(getmajor(sp->s_dev))) + if (vp->v_stream) return ((offset_t)-1); else if (csp->s_flag & SANYOFFSET) /* D_U64BIT */ return ((offset_t)-1); @@ -847,7 +845,7 @@ device_close(struct vnode *vp, int flag, struct cred *cr) switch (type) { case VCHR: - if (STREAMSTAB(getmajor(dev))) { + if (vp->v_stream) { if (cvp->v_stream != NULL) error = strclose(cvp, flag, cr); vp->v_stream = NULL; diff --git a/usr/src/uts/common/fs/specfs/specvnops.c b/usr/src/uts/common/fs/specfs/specvnops.c index 94183f2f76..de3aae70fa 100644 --- a/usr/src/uts/common/fs/specfs/specvnops.c +++ b/usr/src/uts/common/fs/specfs/specvnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -637,10 +637,21 @@ spec_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *cc) (devopsp[maj]->devo_cb_ops->cb_open == NULL)) return (ENXIO); - /* split streams .vs. non-streams */ - if (STREAMSTAB(maj)) + /* + * split STREAMS vs. non-STREAMS + * + * If the device is a dual-personality device, then we might want + * to allow for a regular OTYP_BLK open. If however it's strictly + * a pure STREAMS device, the cb_open entry point will be + * nodev() which returns ENXIO. This does make this failure path + * somewhat longer, but such attempts to use OTYP_BLK with STREAMS + * devices should be exceedingly rare. (Most of the time they will + * be due to programmer error.) + */ + if ((vp->v_type == VCHR) && (STREAMSTAB(maj))) goto streams_open; +not_streams: /* * Wait for in progress last close to complete. This guarantees * to the driver writer that we will never be in the drivers @@ -751,9 +762,6 @@ spec_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *cc) return (error); streams_open: - if (vp->v_type != VCHR) - return (ENXIO); - /* * Lock common snode to prevent any new clone opens on this * stream while one is in progress. This is necessary since @@ -846,6 +854,14 @@ streams_open: SN_RELE(csp); } + /* + * Resolution for STREAMS vs. regular character device: If the + * STREAMS open(9e) returns ENOSTR, then try an ordinary device + * open instead. + */ + if (error == ENOSTR) { + goto not_streams; + } return (error); } @@ -972,7 +988,7 @@ spec_read( ASSERT(vp->v_type == VCHR || vp->v_type == VBLK); - if (STREAMSTAB(getmajor(dev))) { /* stream */ + if (vp->v_stream) { ASSERT(vp->v_type == VCHR); smark(sp, SACC); return (strread(vp, uiop, cr)); @@ -994,7 +1010,7 @@ spec_read( if (vp->v_type == VCHR) { smark(sp, SACC); - ASSERT(STREAMSTAB(getmajor(dev)) == 0); + ASSERT(vp->v_stream == NULL); return (cdev_read(dev, uiop, cr)); } @@ -1078,7 +1094,7 @@ spec_write( ASSERT(vp->v_type == VCHR || vp->v_type == VBLK); - if (STREAMSTAB(getmajor(dev))) { + if (vp->v_stream) { ASSERT(vp->v_type == VCHR); smark(sp, SUPD); return (strwrite(vp, uiop, cr)); @@ -1097,7 +1113,7 @@ spec_write( if (vp->v_type == VCHR) { smark(sp, SUPD); - ASSERT(STREAMSTAB(getmajor(dev)) == 0); + ASSERT(vp->v_stream == NULL); return (cdev_write(dev, uiop, cr)); } @@ -1258,7 +1274,7 @@ spec_ioctl(struct vnode *vp, int cmd, intptr_t arg, int mode, struct cred *cr, sp = VTOS(vp); dev = sp->s_dev; - if (STREAMSTAB(getmajor(dev))) { + if (vp->v_stream) { error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp); } else { error = cdev_ioctl(dev, cmd, arg, mode, cr, rvalp); @@ -2210,7 +2226,7 @@ spec_poll( else { ASSERT(vp->v_type == VCHR); dev = vp->v_rdev; - if (STREAMSTAB(getmajor(dev))) { + if (vp->v_stream) { ASSERT(vp->v_stream != NULL); error = strpoll(vp->v_stream, events, anyyet, reventsp, phpp); diff --git a/usr/src/uts/common/os/driver_lyr.c b/usr/src/uts/common/os/driver_lyr.c index 525fd399cc..fafb02ad89 100644 --- a/usr/src/uts/common/os/driver_lyr.c +++ b/usr/src/uts/common/os/driver_lyr.c @@ -382,7 +382,7 @@ handle_alloc(vnode_t *vp, struct ldi_ident *ident) /* set the device type for this handle */ lhp->lh_type = 0; - if (STREAMSTAB(getmajor(vp->v_rdev))) { + if (vp->v_stream) { ASSERT(vp->v_type == VCHR); lhp->lh_type |= LH_STREAM; } else { @@ -524,11 +524,6 @@ ldi_vp_from_dev(dev_t dev, int otyp, vnode_t **vpp) if ((dip = e_ddi_hold_devi_by_dev(dev, 0)) == NULL) return (ENODEV); - if (STREAMSTAB(getmajor(dev)) && (otyp != OTYP_CHR)) { - ddi_release_devi(dip); /* from e_ddi_hold_devi_by_dev */ - return (ENXIO); - } - vp = makespecvp(dev, OTYP_TO_VTYP(otyp)); spec_assoc_vp_with_devi(vp, dip); ddi_release_devi(dip); /* from e_ddi_hold_devi_by_dev */ @@ -3236,8 +3231,7 @@ ldi_ev_register_callbacks(ldi_handle_t lh, ldi_ev_cookie_t cookie, */ lecp->lec_lhp = lhp; lecp->lec_dev = lhp->lh_vp->v_rdev; - lecp->lec_spec = (lhp->lh_vp->v_type == VCHR) ? - S_IFCHR : S_IFBLK; + lecp->lec_spec = VTYP_TO_STYP(lhp->lh_vp->v_type); lecp->lec_notify = callb->cb_notify; lecp->lec_finalize = callb->cb_finalize; lecp->lec_arg = arg; |