git: 45786883b076 - stable/13 - swapoff(2): add a SWAPOFF_FORCE flag

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 20 Dec 2021 00:38:07 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=45786883b0761dcd13495be67d3e7959b0657609

commit 45786883b0761dcd13495be67d3e7959b0657609
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-29 16:28:19 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-20 00:29:11 +0000

    swapoff(2): add a SWAPOFF_FORCE flag
    
    (cherry picked from commit e8dc2ba29c62f3be2bdeb1a09321d73644a84475)
---
 sys/vm/swap_pager.c | 12 ++++++------
 sys/vm/swap_pager.h |  2 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 17722f314650..9238ecd5645d 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -470,7 +470,7 @@ static void	swp_pager_free_empty_swblk(vm_object_t, struct swblk *sb);
 static int	swapongeom(struct vnode *);
 static int	swaponvp(struct thread *, struct vnode *, u_long);
 static int	swapoff_one(struct swdevt *sp, struct ucred *cred,
-		    bool ignore_check);
+		    u_int flags);
 
 /*
  * Swap bitmap functions
@@ -2505,7 +2505,7 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap)
 		error = copyin(uap->name, &sa, sizeof(sa));
 		if (error != 0)
 			return (error);
-		if (sa.flags != 0)
+		if ((sa.flags & ~(SWAPOFF_FORCE)) != 0)
 			return (EINVAL);
 		break;
 	default:
@@ -2534,14 +2534,14 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap)
 		error = EINVAL;
 		goto done;
 	}
-	error = swapoff_one(sp, td->td_ucred, false);
+	error = swapoff_one(sp, td->td_ucred, sa.flags);
 done:
 	sx_xunlock(&swdev_syscall_lock);
 	return (error);
 }
 
 static int
-swapoff_one(struct swdevt *sp, struct ucred *cred, bool ignore_check)
+swapoff_one(struct swdevt *sp, struct ucred *cred, u_int flags)
 {
 	u_long nblks;
 #ifdef MAC
@@ -2571,7 +2571,7 @@ swapoff_one(struct swdevt *sp, struct ucred *cred, bool ignore_check)
 	 * means that we can lose swap data when filesystems go away,
 	 * which is arguably worse.
 	 */
-	if (!ignore_check &&
+	if ((flags & SWAPOFF_FORCE) == 0 &&
 	    vm_free_count() + swap_pager_avail < nblks + nswap_lowat)
 		return (ENOMEM);
 
@@ -2622,7 +2622,7 @@ swapoff_all(void)
 			devname = devtoname(sp->sw_vp->v_rdev);
 		else
 			devname = "[file]";
-		error = swapoff_one(sp, thread0.td_ucred, true);
+		error = swapoff_one(sp, thread0.td_ucred, SWAPOFF_FORCE);
 		if (error != 0) {
 			printf("Cannot remove swap device %s (error=%d), "
 			    "skipping.\n", devname, error);
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index ed0abdee7d3f..b78ac6a7c698 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -76,6 +76,8 @@ struct swapoff_new_args {
 	uintptr_t pad1[8];
 };
 
+#define	SWAPOFF_FORCE	0x00000001
+
 #ifdef _KERNEL
 
 extern int swap_pager_avail;