svn commit: r363296 - head/sys/vm

Chuck Silvers chs at FreeBSD.org
Fri Jul 17 23:10:36 UTC 2020


Author: chs
Date: Fri Jul 17 23:10:35 2020
New Revision: 363296
URL: https://svnweb.freebsd.org/changeset/base/363296

Log:
  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

Modified:
  head/sys/vm/vnode_pager.c

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Fri Jul 17 23:09:36 2020	(r363295)
+++ head/sys/vm/vnode_pager.c	Fri Jul 17 23:10:35 2020	(r363296)
@@ -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);


More information about the svn-src-all mailing list