| 1491 | } |
| 1492 | |
| 1493 | int |
| 1494 | vn_io_fault_pgmove(vm_page_t ma[], vm_offset_t offset, int xfersize, |
| 1495 | struct uio *uio) |
| 1496 | { |
| 1497 | struct thread *td; |
| 1498 | vm_offset_t iov_base; |
| 1499 | int cnt, pgadv; |
| 1500 | |
| 1501 | td = curthread; |
| 1502 | if ((td->td_pflags & TDP_UIOHELD) == 0 || |
| 1503 | uio->uio_segflg != UIO_USERSPACE) |
| 1504 | return (uiomove_fromphys(ma, offset, xfersize, uio)); |
| 1505 | |
| 1506 | KASSERT(uio->uio_iovcnt == 1, ("uio_iovcnt %d", uio->uio_iovcnt)); |
| 1507 | cnt = xfersize > uio->uio_resid ? uio->uio_resid : xfersize; |
| 1508 | iov_base = (vm_offset_t)uio->uio_iov->iov_base; |
| 1509 | switch (uio->uio_rw) { |
| 1510 | case UIO_WRITE: |
| 1511 | pmap_copy_pages(td->td_ma, iov_base & PAGE_MASK, ma, |
| 1512 | offset, cnt); |
| 1513 | break; |
| 1514 | case UIO_READ: |
| 1515 | pmap_copy_pages(ma, offset, td->td_ma, iov_base & PAGE_MASK, |
| 1516 | cnt); |
| 1517 | break; |
| 1518 | } |
| 1519 | pgadv = ((iov_base + cnt) >> PAGE_SHIFT) - (iov_base >> PAGE_SHIFT); |
| 1520 | td->td_ma += pgadv; |
| 1521 | KASSERT(td->td_ma_cnt >= pgadv, ("consumed pages %d %d", td->td_ma_cnt, |
| 1522 | pgadv)); |
| 1523 | td->td_ma_cnt -= pgadv; |
| 1524 | uio->uio_iov->iov_base = (char *)(iov_base + cnt); |
| 1525 | uio->uio_iov->iov_len -= cnt; |
| 1526 | uio->uio_resid -= cnt; |
| 1527 | uio->uio_offset += cnt; |
| 1528 | return (0); |
| 1529 | } |
| 1530 | |
| 1531 | /* |
| 1532 | * File table truncate routine. |
no test coverage detected