| 600 | } |
| 601 | |
| 602 | static void |
| 603 | soaio_process_job(struct socket *so, struct sockbuf *sb, struct kaiocb *job) |
| 604 | { |
| 605 | struct ucred *td_savedcred; |
| 606 | struct thread *td; |
| 607 | struct file *fp; |
| 608 | size_t cnt, done, job_total_nbytes; |
| 609 | long ru_before; |
| 610 | int error, flags; |
| 611 | |
| 612 | SOCKBUF_UNLOCK(sb); |
| 613 | aio_switch_vmspace(job); |
| 614 | td = curthread; |
| 615 | fp = job->fd_file; |
| 616 | retry: |
| 617 | td_savedcred = td->td_ucred; |
| 618 | td->td_ucred = job->cred; |
| 619 | |
| 620 | job_total_nbytes = job->uiop->uio_resid + job->aio_done; |
| 621 | done = job->aio_done; |
| 622 | cnt = job->uiop->uio_resid; |
| 623 | job->uiop->uio_offset = 0; |
| 624 | job->uiop->uio_td = td; |
| 625 | flags = MSG_NBIO; |
| 626 | |
| 627 | /* |
| 628 | * For resource usage accounting, only count a completed request |
| 629 | * as a single message to avoid counting multiple calls to |
| 630 | * sosend/soreceive on a blocking socket. |
| 631 | */ |
| 632 | |
| 633 | if (sb == &so->so_rcv) { |
| 634 | ru_before = td->td_ru.ru_msgrcv; |
| 635 | #ifdef MAC |
| 636 | error = mac_socket_check_receive(fp->f_cred, so); |
| 637 | if (error == 0) |
| 638 | |
| 639 | #endif |
| 640 | error = soreceive(so, NULL, job->uiop, NULL, NULL, |
| 641 | &flags); |
| 642 | if (td->td_ru.ru_msgrcv != ru_before) |
| 643 | job->msgrcv = 1; |
| 644 | } else { |
| 645 | if (!TAILQ_EMPTY(&sb->sb_aiojobq)) |
| 646 | flags |= MSG_MORETOCOME; |
| 647 | ru_before = td->td_ru.ru_msgsnd; |
| 648 | #ifdef MAC |
| 649 | error = mac_socket_check_send(fp->f_cred, so); |
| 650 | if (error == 0) |
| 651 | #endif |
| 652 | error = sosend(so, NULL, job->uiop, NULL, NULL, flags, |
| 653 | td); |
| 654 | if (td->td_ru.ru_msgsnd != ru_before) |
| 655 | job->msgsnd = 1; |
| 656 | if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { |
| 657 | PROC_LOCK(job->userproc); |
| 658 | kern_psignal(job->userproc, SIGPIPE); |
| 659 | PROC_UNLOCK(job->userproc); |
no test coverage detected