Module Name:    src
Committed By:   hannken
Date:           Tue Feb 16 09:56:32 UTC 2021

Modified Files:
        src/sys/kern: vfs_mount.c
        src/sys/uvm: uvm_swap.c

Log Message:
Reorganize uvm_swap_shutdown() a bit, make sure the vnode gets
locked and referenced across the call to swap_off() and finally
use it from vfs_unmountall1() to remove swap after unmounting
the last file system.

Adresses PR kern/54969 (Disk cache is no longer flushed on shutdown)


To generate a diff of this commit:
cvs rdiff -u -r1.85 -r1.86 src/sys/kern/vfs_mount.c
cvs rdiff -u -r1.200 -r1.201 src/sys/uvm/uvm_swap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_mount.c
diff -u src/sys/kern/vfs_mount.c:1.85 src/sys/kern/vfs_mount.c:1.86
--- src/sys/kern/vfs_mount.c:1.85	Thu Nov 19 10:47:47 2020
+++ src/sys/kern/vfs_mount.c	Tue Feb 16 09:56:32 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_mount.c,v 1.85 2020/11/19 10:47:47 hannken Exp $	*/
+/*	$NetBSD: vfs_mount.c,v 1.86 2021/02/16 09:56:32 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.85 2020/11/19 10:47:47 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.86 2021/02/16 09:56:32 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -94,6 +94,8 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,
 #include <miscfs/genfs/genfs.h>
 #include <miscfs/specfs/specdev.h>
 
+#include <uvm/uvm_swap.h>
+
 enum mountlist_type {
 	ME_MOUNT,
 	ME_MARKER
@@ -1022,6 +1024,7 @@ bool
 vfs_unmountall1(struct lwp *l, bool force, bool verbose)
 {
 	struct mount *mp;
+	mount_iterator_t *iter;
 	bool any_error = false, progress = false;
 	uint64_t gen;
 	int error;
@@ -1056,6 +1059,13 @@ vfs_unmountall1(struct lwp *l, bool forc
 	if (any_error && verbose) {
 		printf("WARNING: some file systems would not unmount\n");
 	}
+	/* If the mountlist is empty it is time to remove swap. */
+	mountlist_iterator_init(&iter);
+	if (mountlist_iterator_next(iter) == NULL) {
+		uvm_swap_shutdown(l);
+	}
+	mountlist_iterator_destroy(iter);
+
 	return progress;
 }
 

Index: src/sys/uvm/uvm_swap.c
diff -u src/sys/uvm/uvm_swap.c:1.200 src/sys/uvm/uvm_swap.c:1.201
--- src/sys/uvm/uvm_swap.c:1.200	Wed Oct  7 17:51:50 2020
+++ src/sys/uvm/uvm_swap.c	Tue Feb 16 09:56:32 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_swap.c,v 1.200 2020/10/07 17:51:50 chs Exp $	*/
+/*	$NetBSD: uvm_swap.c,v 1.201 2021/02/16 09:56:32 hannken Exp $	*/
 
 /*
  * Copyright (c) 1995, 1996, 1997, 2009 Matthew R. Green
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.200 2020/10/07 17:51:50 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.201 2021/02/16 09:56:32 hannken Exp $");
 
 #include "opt_uvmhist.h"
 #include "opt_compat_netbsd.h"
@@ -1152,27 +1152,23 @@ again:
 			if ((sdp->swd_flags & (SWF_INUSE|SWF_ENABLE)) == 0)
 				continue;
 #ifdef DEBUG
-			printf("\nturning off swap on %s...",
-			    sdp->swd_path);
+			printf("\nturning off swap on %s...", sdp->swd_path);
 #endif
+			/* Have to lock and reference vnode for swap_off(). */
 			if (vn_lock(vp = sdp->swd_vp, LK_EXCLUSIVE)) {
 				error = EBUSY;
-				vp = NULL;
-			} else
-				error = 0;
-			if (!error) {
+			} else {
+				vref(vp);
 				error = swap_off(l, sdp);
+				vput(vp);
 				mutex_enter(&uvm_swap_data_lock);
 			}
 			if (error) {
 				printf("stopping swap on %s failed "
 				    "with error %d\n", sdp->swd_path, error);
-				TAILQ_REMOVE(&spp->spi_swapdev, sdp,
-				    swd_next);
+				TAILQ_REMOVE(&spp->spi_swapdev, sdp, swd_next);
 				uvmexp.nswapdev--;
 				swaplist_trim();
-				if (vp)
-					vput(vp);
 			}
 			goto again;
 		}

Reply via email to