Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_physio.c
Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if(dev->si_iosize_max < PAGE_SIZE) { | ||||
dev->si_iosize_max = DFLTPHYS; | dev->si_iosize_max = DFLTPHYS; | ||||
} | } | ||||
/* | /* | ||||
* If the driver does not want I/O to be split, that means that we | * If the driver does not want I/O to be split, that means that we | ||||
* need to reject any requests that will not fit into one buffer. | * need to reject any requests that will not fit into one buffer. | ||||
*/ | */ | ||||
if (dev->si_flags & SI_NOSPLIT && | if (dev->si_flags & SI_NOSPLIT && | ||||
(uio->uio_resid > dev->si_iosize_max || uio->uio_resid > MAXPHYS || | (uio->uio_resid > dev->si_iosize_max || uio->uio_resid > maxphys || | ||||
uio->uio_iovcnt > 1)) { | uio->uio_iovcnt > 1)) { | ||||
/* | /* | ||||
* Tell the user why his I/O was rejected. | * Tell the user why his I/O was rejected. | ||||
*/ | */ | ||||
if (uio->uio_resid > dev->si_iosize_max) | if (uio->uio_resid > dev->si_iosize_max) | ||||
uprintf("%s: request size=%zd > si_iosize_max=%d; " | uprintf("%s: request size=%zd > si_iosize_max=%d; " | ||||
"cannot split request\n", devtoname(dev), | "cannot split request\n", devtoname(dev), | ||||
uio->uio_resid, dev->si_iosize_max); | uio->uio_resid, dev->si_iosize_max); | ||||
if (uio->uio_resid > MAXPHYS) | if (uio->uio_resid > maxphys) | ||||
uprintf("%s: request size=%zd > MAXPHYS=%d; " | uprintf("%s: request size=%zd > maxphys=%lu; " | ||||
"cannot split request\n", devtoname(dev), | "cannot split request\n", devtoname(dev), | ||||
uio->uio_resid, MAXPHYS); | uio->uio_resid, maxphys); | ||||
if (uio->uio_iovcnt > 1) | if (uio->uio_iovcnt > 1) | ||||
uprintf("%s: request vectors=%d > 1; " | uprintf("%s: request vectors=%d > 1; " | ||||
"cannot split request\n", devtoname(dev), | "cannot split request\n", devtoname(dev), | ||||
uio->uio_iovcnt); | uio->uio_iovcnt); | ||||
return (EFBIG); | return (EFBIG); | ||||
} | } | ||||
/* | /* | ||||
* Keep the process UPAGES from being swapped. Processes swapped | * Keep the process UPAGES from being swapped. Processes swapped | ||||
* out while holding pbufs, used by swapper, may lead to deadlock. | * out while holding pbufs, used by swapper, may lead to deadlock. | ||||
*/ | */ | ||||
PHOLD(curproc); | PHOLD(curproc); | ||||
bp = g_alloc_bio(); | bp = g_alloc_bio(); | ||||
if (uio->uio_segflg != UIO_USERSPACE) { | if (uio->uio_segflg != UIO_USERSPACE) { | ||||
pbuf = NULL; | pbuf = NULL; | ||||
pages = NULL; | pages = NULL; | ||||
} else if ((dev->si_flags & SI_UNMAPPED) && unmapped_buf_allowed) { | } else if ((dev->si_flags & SI_UNMAPPED) && unmapped_buf_allowed) { | ||||
pbuf = NULL; | pbuf = NULL; | ||||
maxpages = btoc(MIN(uio->uio_resid, MAXPHYS)) + 1; | maxpages = btoc(MIN(uio->uio_resid, maxphys)) + 1; | ||||
pages = malloc(sizeof(*pages) * maxpages, M_DEVBUF, M_WAITOK); | pages = malloc(sizeof(*pages) * maxpages, M_DEVBUF, M_WAITOK); | ||||
} else { | } else { | ||||
pbuf = uma_zalloc(pbuf_zone, M_WAITOK); | pbuf = uma_zalloc(pbuf_zone, M_WAITOK); | ||||
MPASS((pbuf->b_flags & B_MAXPHYS) != 0); | |||||
sa = pbuf->b_data; | sa = pbuf->b_data; | ||||
maxpages = btoc(MAXPHYS); | maxpages = btoc(maxphys); | ||||
pages = pbuf->b_pages; | pages = pbuf->b_pages; | ||||
} | } | ||||
prot = VM_PROT_READ; | prot = VM_PROT_READ; | ||||
if (uio->uio_rw == UIO_READ) | if (uio->uio_rw == UIO_READ) | ||||
prot |= VM_PROT_WRITE; /* Less backwards than it looks */ | prot |= VM_PROT_WRITE; /* Less backwards than it looks */ | ||||
error = 0; | error = 0; | ||||
for (i = 0; i < uio->uio_iovcnt; i++) { | for (i = 0; i < uio->uio_iovcnt; i++) { | ||||
#ifdef RACCT | #ifdef RACCT | ||||
Show All 21 Lines | while (uio->uio_iov[i].iov_len) { | ||||
bp->bio_cmd = BIO_WRITE; | bp->bio_cmd = BIO_WRITE; | ||||
curthread->td_ru.ru_oublock++; | curthread->td_ru.ru_oublock++; | ||||
} | } | ||||
bp->bio_offset = uio->uio_offset; | bp->bio_offset = uio->uio_offset; | ||||
base = uio->uio_iov[i].iov_base; | base = uio->uio_iov[i].iov_base; | ||||
bp->bio_length = uio->uio_iov[i].iov_len; | bp->bio_length = uio->uio_iov[i].iov_len; | ||||
if (bp->bio_length > dev->si_iosize_max) | if (bp->bio_length > dev->si_iosize_max) | ||||
bp->bio_length = dev->si_iosize_max; | bp->bio_length = dev->si_iosize_max; | ||||
if (bp->bio_length > MAXPHYS) | if (bp->bio_length > maxphys) | ||||
bp->bio_length = MAXPHYS; | bp->bio_length = maxphys; | ||||
/* | /* | ||||
* Make sure the pbuf can map the request. | * Make sure the pbuf can map the request. | ||||
* The pbuf has kvasize = MAXPHYS, so a request | * The pbuf has kvasize = maxphys, so a request | ||||
* larger than MAXPHYS - PAGE_SIZE must be | * larger than maxphys - PAGE_SIZE must be | ||||
* page aligned or it will be fragmented. | * page aligned or it will be fragmented. | ||||
*/ | */ | ||||
poff = (vm_offset_t)base & PAGE_MASK; | poff = (vm_offset_t)base & PAGE_MASK; | ||||
if (pbuf && bp->bio_length + poff > pbuf->b_kvasize) { | if (pbuf && bp->bio_length + poff > pbuf->b_kvasize) { | ||||
if (dev->si_flags & SI_NOSPLIT) { | if (dev->si_flags & SI_NOSPLIT) { | ||||
uprintf("%s: request ptr %p is not " | uprintf("%s: request ptr %p is not " | ||||
"on a page boundary; cannot split " | "on a page boundary; cannot split " | ||||
"request\n", devtoname(dev), | "request\n", devtoname(dev), | ||||
▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines |