* Map the sending processes' buffer into kernel space and wire it. * This is similar to a physical write operation. */
| 868 | * This is similar to a physical write operation. |
| 869 | */ |
| 870 | static int |
| 871 | pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio) |
| 872 | { |
| 873 | u_int size; |
| 874 | int i; |
| 875 | |
| 876 | PIPE_LOCK_ASSERT(wpipe, MA_OWNED); |
| 877 | KASSERT((wpipe->pipe_state & PIPE_DIRECTW) == 0, |
| 878 | ("%s: PIPE_DIRECTW set on %p", __func__, wpipe)); |
| 879 | KASSERT(wpipe->pipe_pages.cnt == 0, |
| 880 | ("%s: pipe map for %p contains residual data", __func__, wpipe)); |
| 881 | |
| 882 | if (uio->uio_iov->iov_len > wpipe->pipe_buffer.size) |
| 883 | size = wpipe->pipe_buffer.size; |
| 884 | else |
| 885 | size = uio->uio_iov->iov_len; |
| 886 | |
| 887 | wpipe->pipe_state |= PIPE_DIRECTW; |
| 888 | PIPE_UNLOCK(wpipe); |
| 889 | i = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map, |
| 890 | (vm_offset_t)uio->uio_iov->iov_base, size, VM_PROT_READ, |
| 891 | wpipe->pipe_pages.ms, PIPENPAGES); |
| 892 | PIPE_LOCK(wpipe); |
| 893 | if (i < 0) { |
| 894 | wpipe->pipe_state &= ~PIPE_DIRECTW; |
| 895 | return (EFAULT); |
| 896 | } |
| 897 | |
| 898 | wpipe->pipe_pages.npages = i; |
| 899 | wpipe->pipe_pages.pos = |
| 900 | ((vm_offset_t) uio->uio_iov->iov_base) & PAGE_MASK; |
| 901 | wpipe->pipe_pages.cnt = size; |
| 902 | |
| 903 | uio->uio_iov->iov_len -= size; |
| 904 | uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + size; |
| 905 | if (uio->uio_iov->iov_len == 0) |
| 906 | uio->uio_iov++; |
| 907 | uio->uio_resid -= size; |
| 908 | uio->uio_offset += size; |
| 909 | return (0); |
| 910 | } |
| 911 | |
| 912 | /* |
| 913 | * Unwire the process buffer. |
no test coverage detected