git: 40c1672e886b - main - swap_pager: fix seek_data with invalid first page

From: Doug Moore <dougm_at_FreeBSD.org>
Date: Tue, 26 Nov 2024 18:15:33 UTC
The branch main has been updated by dougm:

URL: https://cgit.FreeBSD.org/src/commit/?id=40c1672e886b86f4956c16e9f1161683328504ff

commit 40c1672e886b86f4956c16e9f1161683328504ff
Author:     Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2024-11-26 18:12:08 +0000
Commit:     Doug Moore <dougm@FreeBSD.org>
CommitDate: 2024-11-26 18:12:08 +0000

    swap_pager: fix seek_data with invalid first page
    
    Correct swap_pager_seek_data so that, when the first lookup finds no
    valid pages, second and subsequent lookups are attempted anyway.
    
    This was broken by db08b0b04deced766c3b5f07bcfb82333666226c.
    
    Reported by:    marklmi@yahoo.com
    Reviewed by:    kib
    Tested by:      marklmi@yahoo.com
    Fixes:  db08b0b04deced76 tmpfs_vnops: move swap work to swap_pager
    Differential Revision:  https://reviews.freebsd.org/D47767
---
 sys/vm/swap_pager.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index db925f4ae7f6..3d02f365cad9 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -2503,26 +2503,23 @@ swap_pager_seek_data(vm_object_t object, vm_pindex_t pindex)
 	VM_OBJECT_ASSERT_RLOCKED(object);
 	vm_page_iter_init(&pages, object);
 	m = vm_page_iter_lookup_ge(&pages, pindex);
-	if (m != NULL) {
-		if (!vm_page_any_valid(m))
-			m = NULL;
-		else if (pages.index == pindex)
-			return (pages.index);
-	}
+	if (m != NULL && pages.index == pindex && vm_page_any_valid(m))
+		return (pages.index);
 	swblk_iter_init_only(&blks, object);
 	swap_index = swap_pager_iter_find_least(&blks, pindex);
 	if (swap_index == pindex)
 		return (swap_index);
-	if (swap_index == OBJ_MAX_SIZE)
-		swap_index = object->size;
-	if (m == NULL)
-		return (swap_index);
 
-	while ((m = vm_radix_iter_step(&pages)) != NULL &&
-	    pages.index < swap_index) {
+	/*
+	 * Find the first resident page after m, before swap_index.
+	 */
+	while (m != NULL && pages.index < swap_index) {
 		if (vm_page_any_valid(m))
 			return (pages.index);
+		m = vm_radix_iter_step(&pages);
 	}
+	if (swap_index == OBJ_MAX_SIZE)
+		swap_index = object->size;
 	return (swap_index);
 }