Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_sendfile.c
Show First 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static void | static void | ||||
sendfile_iodone(void *arg, vm_page_t *pa, int count, int error) | sendfile_iodone(void *arg, vm_page_t *pa, int count, int error) | ||||
{ | { | ||||
struct sf_io *sfio = arg; | struct sf_io *sfio = arg; | ||||
struct socket *so; | struct socket *so; | ||||
int i; | int i; | ||||
if (error != 0) { | if (error != 0) | ||||
sfio->error = error; | sfio->error = error; | ||||
/* | /* | ||||
* Restore of the pg[] elements is done by | |||||
* sendfile_swapin(). | |||||
*/ | |||||
} else { | |||||
/* | |||||
* Restore the valid page pointers. They are already | * Restore the valid page pointers. They are already | ||||
* unbusied, but still wired. For error != 0 case, | * unbusied, but still wired. | ||||
* sendfile_swapin() handles unbusy. | |||||
* | * | ||||
* XXXKIB since pages are only wired, and we do not | * XXXKIB since pages are only wired, and we do not | ||||
* own the object lock, other users might have | * own the object lock, other users might have | ||||
* invalidated them in meantime. Similarly, after we | * invalidated them in meantime. Similarly, after we | ||||
* unbusied the swapped-in pages, they can become | * unbusied the swapped-in pages, they can become | ||||
* invalid under us. | * invalid under us. | ||||
*/ | */ | ||||
MPASS(count == 0 || pa[0] != bogus_page); | MPASS(count == 0 || pa[0] != bogus_page); | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
if (pa[i] == bogus_page) { | if (pa[i] == bogus_page) { | ||||
sfio->pa[(pa[0]->pindex - sfio->pindex0) + i] = | sfio->pa[(pa[0]->pindex - sfio->pindex0) + i] = | ||||
pa[i] = vm_page_relookup(sfio->obj, | pa[i] = vm_page_relookup(sfio->obj, | ||||
pa[0]->pindex + i); | pa[0]->pindex + i); | ||||
KASSERT(pa[i] != NULL, | KASSERT(pa[i] != NULL, | ||||
("%s: page %p[%d] disappeared", | ("%s: page %p[%d] disappeared", | ||||
__func__, pa, i)); | __func__, pa, i)); | ||||
} else { | } else { | ||||
vm_page_xunbusy_unchecked(pa[i]); | vm_page_xunbusy_unchecked(pa[i]); | ||||
} | } | ||||
} | } | ||||
} | |||||
if (!refcount_release(&sfio->nios)) | if (!refcount_release(&sfio->nios)) | ||||
return; | return; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
for (i = 1; i < sfio->npages; i++) { | for (i = 1; i < sfio->npages; i++) { | ||||
if (sfio->pa[i] == NULL) | if (sfio->pa[i] == NULL) | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | for (i = 0; i < npages;) { | ||||
refcount_acquire(&sfio->nios); | refcount_acquire(&sfio->nios); | ||||
rv = vm_pager_get_pages_async(obj, pa + i, count, NULL, | rv = vm_pager_get_pages_async(obj, pa + i, count, NULL, | ||||
i + count == npages ? &rhpages : NULL, | i + count == npages ? &rhpages : NULL, | ||||
&sendfile_iodone, sfio); | &sendfile_iodone, sfio); | ||||
if (__predict_false(rv != VM_PAGER_OK)) { | if (__predict_false(rv != VM_PAGER_OK)) { | ||||
sendfile_iowait(sfio, "sferrio"); | sendfile_iowait(sfio, "sferrio"); | ||||
/* | /* | ||||
* Perform full pages recovery before returning EIO. | * Perform full pages recovery before returning EIO. | ||||
kib: This i no longer full recovery. it is something like 'the rest of full recovery, other parts… | |||||
* Pages from 0 to npages are wired. | * Pages from 0 to npages are wired. | ||||
* Pages from (i + 1) to (i + count - 1) may be | * Pages from (i + count1) to npages are busied. | ||||
* substituted to bogus page, and not busied. | |||||
* Pages from (i + count) to (i + count1 - 1) are | |||||
* not busied. | |||||
* Rest of the pages from i to npages are busied. | |||||
*/ | */ | ||||
for (j = 0; j < npages; j++) { | for (j = 0; j < npages; j++) { | ||||
if (j >= i + count && j < i + count1) | if (j >= i + count1) | ||||
; | |||||
else if (j > i && j < i + count - 1 && | |||||
pa[j] == bogus_page) | |||||
pa[j] = vm_page_relookup(obj, | |||||
OFF_TO_IDX(vmoff(j, off))); | |||||
else if (j >= i) | |||||
vm_page_xunbusy(pa[j]); | vm_page_xunbusy(pa[j]); | ||||
KASSERT(pa[j] != NULL && pa[j] != bogus_page, | KASSERT(pa[j] != NULL && pa[j] != bogus_page, | ||||
("%s: page %p[%d] I/O recovery failure", | ("%s: page %p[%d] I/O recovery failure", | ||||
__func__, pa, j)); | __func__, pa, j)); | ||||
vm_page_unwire(pa[j], PQ_INACTIVE); | vm_page_unwire(pa[j], PQ_INACTIVE); | ||||
} | } | ||||
return (EIO); | return (EIO); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 792 Lines • Show Last 20 Lines |
This i no longer full recovery. it is something like 'the rest of full recovery, other parts were already done by sendfile_iodone completions'