diff options
Diffstat (limited to 'usr/src/uts/common/os/streamio.c')
-rw-r--r-- | usr/src/uts/common/os/streamio.c | 231 |
1 files changed, 137 insertions, 94 deletions
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c index ffa676604f..e189a1627d 100644 --- a/usr/src/uts/common/os/streamio.c +++ b/usr/src/uts/common/os/streamio.c @@ -77,6 +77,19 @@ #include <sys/autoconf.h> #include <sys/policy.h> + +/* + * This define helps improve the readability of streams code while + * still maintaining a very old streams performance enhancement. The + * performance enhancement basically involved having all callers + * of straccess() perform the first check that straccess() will do + * locally before actually calling straccess(). (There by reducing + * the number of unnecessary calls to straccess().) + */ +#define i_straccess(x, y) ((stp->sd_sidp == NULL) ? 0 : \ + (stp->sd_vnode->v_type == VFIFO) ? 0 : \ + straccess((x), (y))) + /* * what is mblk_pull_len? * @@ -1095,11 +1108,13 @@ strread(struct vnode *vp, struct uio *uiop, cred_t *crp) ASSERT(vp->v_stream); stp = vp->v_stream; - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, JCREAD)) - return (error); - mutex_enter(&stp->sd_lock); + + if ((error = i_straccess(stp, JCREAD)) != 0) { + mutex_exit(&stp->sd_lock); + return (error); + } + if (stp->sd_flag & (STRDERR|STPLEX)) { error = strgeterr(stp, STRDERR|STPLEX, 0); if (error != 0) { @@ -1161,12 +1176,8 @@ strread(struct vnode *vp, struct uio *uiop, cred_t *crp) } TRACE_3(TR_FAC_STREAMS_FR, TR_STRREAD_AWAKE, "strread awakes:%p, %p, %p", vp, uiop, crp); - if (stp->sd_sidp != NULL && - stp->sd_vnode->v_type != VFIFO) { - mutex_exit(&stp->sd_lock); - if (error = straccess(stp, JCREAD)) - goto oops1; - mutex_enter(&stp->sd_lock); + if ((error = i_straccess(stp, JCREAD)) != 0) { + goto oops; } first = 0; } @@ -2026,8 +2037,8 @@ strrput_nondata(queue_t *q, mblk_t *bp) cv_broadcast(&q->q_wait); /* the readers */ cv_broadcast(&_WR(q)->q_wait); /* the writers */ cv_broadcast(&stp->sd_monitor); /* the ioctllers */ - mutex_exit(&stp->sd_lock); strhup(stp); + mutex_exit(&stp->sd_lock); return (0); case M_UNHANGUP: @@ -2665,18 +2676,23 @@ strwrite_common(struct vnode *vp, struct uio *uiop, cred_t *crp, int wflag) ASSERT(vp->v_stream); stp = vp->v_stream; - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) - if ((error = straccess(stp, JCWRITE)) != 0) - return (error); + mutex_enter(&stp->sd_lock); + + if ((error = i_straccess(stp, JCWRITE)) != 0) { + mutex_exit(&stp->sd_lock); + return (error); + } if (stp->sd_flag & (STWRERR|STRHUP|STPLEX)) { - mutex_enter(&stp->sd_lock); error = strwriteable(stp, B_TRUE, B_TRUE); - mutex_exit(&stp->sd_lock); - if (error != 0) + if (error != 0) { + mutex_exit(&stp->sd_lock); return (error); + } } + mutex_exit(&stp->sd_lock); + wqp = stp->sd_wrq; /* get these values from them cached in the stream head */ @@ -2778,11 +2794,11 @@ strwrite_common(struct vnode *vp, struct uio *uiop, cred_t *crp, int wflag) } TRACE_1(TR_FAC_STREAMS_FR, TR_STRWRITE_WAKE, "strwrite wake:q %p awakes", wqp); + if ((error = i_straccess(stp, JCWRITE)) != 0) { + mutex_exit(&stp->sd_lock); + goto out; + } mutex_exit(&stp->sd_lock); - if (stp->sd_sidp != NULL && - stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, JCWRITE)) - goto out; } waitflag |= NOINTR; TRACE_2(TR_FAC_STREAMS_FR, TR_STRWRITE_RESID, @@ -3101,6 +3117,7 @@ job_control_type(int cmd) case JAGENT: /* Obsolete */ case JTRUN: /* Obsolete */ case JXTPROTO: /* Obsolete */ + case TIOCSETLD: return (JCSETP); } @@ -3162,10 +3179,12 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, if (cmd == SRIOCSREDIR || cmd == SRIOCISREDIR) return (EINVAL); - if (access != -1 && stp->sd_sidp != NULL && - stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, access)) - return (error); + mutex_enter(&stp->sd_lock); + if ((access != -1) && ((error = i_straccess(stp, access)) != 0)) { + mutex_exit(&stp->sd_lock); + return (error); + } + mutex_exit(&stp->sd_lock); /* * Check for sgttyb-related ioctls first, and complain as @@ -3307,11 +3326,16 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, secpolicy_sti(crp) != 0) { return (EPERM); } - if (stp->sd_sidp != - ttoproc(curthread)->p_sessp->s_sidp && + mutex_enter(&stp->sd_lock); + mutex_enter(&curproc->p_splock); + if (stp->sd_sidp != curproc->p_sessp->s_sidp && secpolicy_sti(crp) != 0) { + mutex_exit(&curproc->p_splock); + mutex_exit(&stp->sd_lock); return (EACCES); } + mutex_exit(&curproc->p_splock); + mutex_exit(&stp->sd_lock); strioc.ic_len = sizeof (char); strioc.ic_dp = (char *)arg; @@ -3445,10 +3469,13 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, return (EINVAL); access = job_control_type(strioc.ic_cmd); - if (access != -1 && stp->sd_sidp != NULL && - stp->sd_vnode->v_type != VFIFO && - (error = straccess(stp, access)) != 0) + mutex_enter(&stp->sd_lock); + if ((access != -1) && + ((error = i_straccess(stp, access)) != 0)) { + mutex_exit(&stp->sd_lock); return (error); + } + mutex_exit(&stp->sd_lock); /* * The I_STR facility provides a trap door for malicious @@ -3699,7 +3726,7 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, /* * try to allocate it as a controlling terminal */ - stralloctty(stp); + (void) strctty(stp); } } @@ -5053,15 +5080,11 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, releasef(STRUCT_FGET(strfdinsert, fildes)); return (error); } - if (stp->sd_sidp != NULL && - stp->sd_vnode->v_type != VFIFO) { + if ((error = i_straccess(stp, access)) != 0) { mutex_exit(&stp->sd_lock); - if (error = straccess(stp, access)) { - releasef( - STRUCT_FGET(strfdinsert, fildes)); - return (error); - } - mutex_enter(&stp->sd_lock); + releasef( + STRUCT_FGET(strfdinsert, fildes)); + return (error); } } mutex_exit(&stp->sd_lock); @@ -5144,12 +5167,9 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, mutex_exit(&stp->sd_lock); return (error); } - if (stp->sd_sidp != NULL && - stp->sd_vnode->v_type != VFIFO) { + if ((error = i_straccess(stp, access)) != 0) { mutex_exit(&stp->sd_lock); - if (error = straccess(stp, access)) - return (error); - mutex_enter(&stp->sd_lock); + return (error); } } if (mp->b_datap->db_type != M_PASSFP) { @@ -5446,13 +5466,13 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, { pid_t sid; - mutex_enter(&pidlock); + mutex_enter(&stp->sd_lock); if (stp->sd_sidp == NULL) { - mutex_exit(&pidlock); + mutex_exit(&stp->sd_lock); return (ENOTTY); } sid = stp->sd_sidp->pid_id; - mutex_exit(&pidlock); + mutex_exit(&stp->sd_lock); return (strcopyout(&sid, (void *)arg, sizeof (pid_t), copyflag)); } @@ -5494,6 +5514,7 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, bg_pgid = stp->sd_pgidp->pid_id; CL_SET_PROCESS_GROUP(curthread, sid, bg_pgid, fg_pgid); PID_RELE(stp->sd_pgidp); + ctty_clear_sighuped(); stp->sd_pgidp = q->p_pgidp; PID_HOLD(stp->sd_pgidp); mutex_exit(&pidlock); @@ -5505,17 +5526,30 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag, { pid_t pgrp; - mutex_enter(&pidlock); + mutex_enter(&stp->sd_lock); if (stp->sd_sidp == NULL) { - mutex_exit(&pidlock); + mutex_exit(&stp->sd_lock); return (ENOTTY); } pgrp = stp->sd_pgidp->pid_id; - mutex_exit(&pidlock); + mutex_exit(&stp->sd_lock); return (strcopyout(&pgrp, (void *)arg, sizeof (pid_t), copyflag)); } + case TIOCSCTTY: + { + return (strctty(stp)); + } + + case TIOCNOTTY: + { + /* freectty() always assumes curproc. */ + if (freectty(B_FALSE) != 0) + return (0); + return (ENOTTY); + } + case FIONBIO: case FIOASYNC: return (0); /* handled by the upper layer */ @@ -6233,18 +6267,21 @@ strgetmsg( stp = vp->v_stream; rvp->r_val1 = 0; - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, JCREAD)) - return (error); + mutex_enter(&stp->sd_lock); + + if ((error = i_straccess(stp, JCREAD)) != 0) { + mutex_exit(&stp->sd_lock); + return (error); + } - /* Fast check of flags before acquiring the lock */ if (stp->sd_flag & (STRDERR|STPLEX)) { - mutex_enter(&stp->sd_lock); error = strgeterr(stp, STRDERR|STPLEX, 0); - mutex_exit(&stp->sd_lock); - if (error != 0) + if (error != 0) { + mutex_exit(&stp->sd_lock); return (error); + } } + mutex_exit(&stp->sd_lock); switch (*flagsp) { case MSG_HIPRI: @@ -6381,11 +6418,9 @@ strgetmsg( } TRACE_2(TR_FAC_STREAMS_FR, TR_STRGETMSG_AWAKE, "strgetmsg awakes:%p, %p", vp, uiop); - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) { + if ((error = i_straccess(stp, JCREAD)) != 0) { mutex_exit(&stp->sd_lock); - if (error = straccess(stp, JCREAD)) - return (error); - mutex_enter(&stp->sd_lock); + return (error); } first = 0; } @@ -6797,23 +6832,26 @@ kstrgetmsg( stp = vp->v_stream; rvp->r_val1 = 0; - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, JCREAD)) - return (error); + mutex_enter(&stp->sd_lock); + + if ((error = i_straccess(stp, JCREAD)) != 0) { + mutex_exit(&stp->sd_lock); + return (error); + } flags = *flagsp; - /* Fast check of flags before acquiring the lock */ if (stp->sd_flag & (STRDERR|STPLEX)) { if ((stp->sd_flag & STPLEX) || (flags & (MSG_IGNERROR|MSG_DELAYERROR)) == 0) { - mutex_enter(&stp->sd_lock); error = strgeterr(stp, STRDERR|STPLEX, (flags & MSG_IPEEK)); - mutex_exit(&stp->sd_lock); - if (error != 0) + if (error != 0) { + mutex_exit(&stp->sd_lock); return (error); + } } } + mutex_exit(&stp->sd_lock); switch (flags & (MSG_HIPRI|MSG_ANY|MSG_BAND)) { case MSG_HIPRI: @@ -6955,11 +6993,9 @@ retry: } TRACE_2(TR_FAC_STREAMS_FR, TR_KSTRGETMSG_AWAKE, "kstrgetmsg awakes:%p, %p", vp, uiop); - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) { + if ((error = i_straccess(stp, JCREAD)) != 0) { mutex_exit(&stp->sd_lock); - if (error = straccess(stp, JCREAD)) - return (error); - mutex_enter(&stp->sd_lock); + return (error); } first = 0; } @@ -7430,18 +7466,23 @@ strputmsg( audit_strputmsg(vp, mctl, mdata, pri, flag, fmode); #endif - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, JCWRITE)) - return (error); + mutex_enter(&stp->sd_lock); + + if ((error = i_straccess(stp, JCWRITE)) != 0) { + mutex_exit(&stp->sd_lock); + return (error); + } if (stp->sd_flag & (STWRERR|STRHUP|STPLEX)) { - mutex_enter(&stp->sd_lock); error = strwriteable(stp, B_FALSE, xpg4); - mutex_exit(&stp->sd_lock); - if (error != 0) + if (error != 0) { + mutex_exit(&stp->sd_lock); return (error); + } } + mutex_exit(&stp->sd_lock); + /* * Check for legal flag value. */ @@ -7561,10 +7602,11 @@ strputmsg( } TRACE_1(TR_FAC_STREAMS_FR, TR_STRPUTMSG_WAKE, "strputmsg wake:stp %p wakes", stp); + if ((error = i_straccess(stp, JCWRITE)) != 0) { + mutex_exit(&stp->sd_lock); + return (error); + } mutex_exit(&stp->sd_lock); - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) - if (error = straccess(stp, JCWRITE)) - return (error); } out: /* @@ -7617,25 +7659,27 @@ kstrputmsg( if (mctl == NULL) return (EINVAL); - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) { - if (error = straccess(stp, JCWRITE)) { - freemsg(mctl); - return (error); - } + mutex_enter(&stp->sd_lock); + + if ((error = i_straccess(stp, JCWRITE)) != 0) { + mutex_exit(&stp->sd_lock); + freemsg(mctl); + return (error); } if ((stp->sd_flag & STPLEX) || !(flag & MSG_IGNERROR)) { if (stp->sd_flag & (STWRERR|STRHUP|STPLEX)) { - mutex_enter(&stp->sd_lock); error = strwriteable(stp, B_FALSE, B_TRUE); - mutex_exit(&stp->sd_lock); if (error != 0) { + mutex_exit(&stp->sd_lock); freemsg(mctl); return (error); } } } + mutex_exit(&stp->sd_lock); + /* * Check for legal flag value. */ @@ -7804,13 +7848,12 @@ kstrputmsg( } TRACE_1(TR_FAC_STREAMS_FR, TR_KSTRPUTMSG_WAKE, "kstrputmsg wake:stp %p wakes", stp); - mutex_exit(&stp->sd_lock); - if (stp->sd_sidp != NULL && stp->sd_vnode->v_type != VFIFO) { - if (error = straccess(stp, JCWRITE)) { - freemsg(mctl); - return (error); - } + if ((error = i_straccess(stp, JCWRITE)) != 0) { + mutex_exit(&stp->sd_lock); + freemsg(mctl); + return (error); } + mutex_exit(&stp->sd_lock); } out: freemsg(mctl); |