Fix vnode_pager handling of read ahead/behind pages when a disk read fails.

Rather than marking the read ahead/behind pages valid even though they were
not initialized, free them using the new function vm_page_free_invalid().

Reviewed by:	markj, kib
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D25430
This commit is contained in:
Chuck Silvers 2020-07-17 23:10:35 +00:00
parent 4dfa06e114
commit 1bd12a3bb2

View File

@ -1139,6 +1139,21 @@ vnode_pager_generic_getpages_done(struct buf *bp)
bp->b_data = unmapped_buf;
}
/*
* If the read failed, we must free any read ahead/behind pages here.
* The requested pages are freed by the caller (for sync requests)
* or by the bp->b_pgiodone callback (for async requests).
*/
if (error != 0) {
VM_OBJECT_WLOCK(object);
for (i = 0; i < bp->b_pgbefore; i++)
vm_page_free_invalid(bp->b_pages[i]);
for (i = bp->b_npages - bp->b_pgafter; i < bp->b_npages; i++)
vm_page_free_invalid(bp->b_pages[i]);
VM_OBJECT_WUNLOCK(object);
return (error);
}
/* Read lock to protect size. */
VM_OBJECT_RLOCK(object);
for (i = 0, tfoff = IDX_TO_OFF(bp->b_pages[0]->pindex);