Print this page
OS-5518 devpoll write feigns success in the face of EINTR
OS-5520 epoll_ctl not allowed to emit EINTR
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
OS-5516 vmxnet3s declares wrong sdu
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Bryan Cantrill <bryan@joyent.com>
OS-5511 epoll should not leave dangling polldat_t entries
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
OS-5260 lxbrand epoll_pwait needs sigset translation
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

*** 351,362 **** */ if (is_epoll) { pdp->pd_fp = NULL; pdp->pd_events = 0; ! if (php != NULL) { ! pollhead_delete(php, pdp); pdp->pd_php = NULL; } BT_CLEAR(pcp->pc_bitmap, fd); continue; --- 351,363 ---- */ if (is_epoll) { pdp->pd_fp = NULL; pdp->pd_events = 0; ! if (pdp->pd_php != NULL) { ! pollhead_delete(pdp->pd_php, ! pdp); pdp->pd_php = NULL; } BT_CLEAR(pcp->pc_bitmap, fd); continue;
*** 501,512 **** */ if (pdp->pd_events & POLLONESHOT) { pdp->pd_fp = NULL; pdp->pd_events = 0; ! if (php != NULL) { ! pollhead_delete(php, pdp); pdp->pd_php = NULL; } BT_CLEAR(pcp->pc_bitmap, fd); } --- 502,514 ---- */ if (pdp->pd_events & POLLONESHOT) { pdp->pd_fp = NULL; pdp->pd_events = 0; ! if (pdp->pd_php != NULL) { ! pollhead_delete(pdp->pd_php, ! pdp); pdp->pd_php = NULL; } BT_CLEAR(pcp->pc_bitmap, fd); }
*** 637,646 **** --- 639,649 ---- pollfd_t *pollfdp, *pfdp; dvpoll_epollfd_t *epfdp; uintptr_t limit; int error, size; ssize_t uiosize; + size_t copysize; nfds_t pollfdnum; struct pollhead *php = NULL; polldat_t *pdp; int fd; file_t *fp;
*** 702,716 **** * not supposed to function as a seekable device. To prevent offset * from growing and eventually exceed the maximum, reset the offset * here for every call. */ uiop->uio_loffset = 0; ! if ((error = uiomove((caddr_t)pollfdp, uiosize, UIO_WRITE, uiop)) ! != 0) { kmem_free(pollfdp, uiosize); return (error); } /* * We are about to enter the core portion of dpwrite(). Make sure this * write has exclusive access in this portion of the code, i.e., no * other writers in this code. * --- 705,727 ---- * not supposed to function as a seekable device. To prevent offset * from growing and eventually exceed the maximum, reset the offset * here for every call. */ uiop->uio_loffset = 0; ! ! /* ! * Use uiocopy instead of uiomove when populating pollfdp, keeping ! * uio_resid untouched for now. Write syscalls will translate EINTR ! * into a success if they detect "successfully transfered" data via an ! * updated uio_resid. Falsely suppressing such errors is disastrous. ! */ ! if ((error = uiocopy((caddr_t)pollfdp, uiosize, UIO_WRITE, uiop, ! &copysize)) != 0) { kmem_free(pollfdp, uiosize); return (error); } + /* * We are about to enter the core portion of dpwrite(). Make sure this * write has exclusive access in this portion of the code, i.e., no * other writers in this code. *
*** 979,988 **** --- 990,1006 ---- dpep->dpe_flag &= ~DP_WRITER_PRESENT; dpep->dpe_refcnt--; cv_broadcast(&dpep->dpe_cv); mutex_exit(&dpep->dpe_lock); kmem_free(pollfdp, uiosize); + if (error == 0) { + /* + * The state of uio_resid is updated only after the pollcache + * is successfully modified. + */ + uioskip(uiop, copysize); + } return (error); } #define DP_SIGMASK_RESTORE(ksetp) { \ if (ksetp != NULL) { \
*** 1121,1137 **** if (cmd == DP_PPOLL) { void *setp = STRUCT_FGETP(dvpoll, dp_setp); if (setp != NULL) { if (copyin(setp, &set, sizeof (set))) { DP_REFRELE(dpep); return (EFAULT); } - sigutok(&set, &kset); ksetp = &kset; mutex_enter(&p->p_lock); schedctl_finish_sigblock(t); lwp->lwp_sigoldmask = t->t_hold; t->t_hold = *ksetp; --- 1139,1159 ---- if (cmd == DP_PPOLL) { void *setp = STRUCT_FGETP(dvpoll, dp_setp); if (setp != NULL) { + if ((mode & FKIOCTL) != 0) { + /* Use the signal set directly */ + ksetp = (k_sigset_t *)setp; + } else { if (copyin(setp, &set, sizeof (set))) { DP_REFRELE(dpep); return (EFAULT); } sigutok(&set, &kset); ksetp = &kset; + } mutex_enter(&p->p_lock); schedctl_finish_sigblock(t); lwp->lwp_sigoldmask = t->t_hold; t->t_hold = *ksetp;
*** 1277,1286 **** --- 1299,1312 ---- pollstate_exit(pcp); DP_SIGMASK_RESTORE(ksetp); if (error == 0 && fdcnt > 0) { + /* + * It should be noted that FKIOCTL does not influence + * the copyout (vs bcopy) of dp_fds at this time. + */ if (copyout(ps->ps_dpbuf, STRUCT_FGETP(dvpoll, dp_fds), fdcnt * fdsize)) { DP_REFRELE(dpep); return (EFAULT); }