Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jul 2020 23:10:35 +0000 (UTC)
From:      Chuck Silvers <chs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r363296 - head/sys/vm
Message-ID:  <202007172310.06HNAalX063964@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007172310.06HNAalX063964>