Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Jun 2019 03:16:02 +0000 (UTC)
From:      Doug Moore <dougm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r349286 - in head: sbin/swapon share/man/man5
Message-ID:  <201906220316.x5M3G2sp095548@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dougm
Date: Sat Jun 22 03:16:01 2019
New Revision: 349286
URL: https://svnweb.freebsd.org/changeset/base/349286

Log:
  Modify swapon(8) to invoke BIO_DELETE to trim swap devices, either if
  '-E' appears on the swapon command line, or if "trimonce" appears as
  an fstab option.
  
  Discussed at: BSDCAN
  Tested by: markj
  Reviewed by: markj
  Approved by: markj (mentor)
  Differential Revision:https://reviews.freebsd.org/D20599

Modified:
  head/sbin/swapon/swapon.8
  head/sbin/swapon/swapon.c
  head/share/man/man5/fstab.5

Modified: head/sbin/swapon/swapon.8
==============================================================================
--- head/sbin/swapon/swapon.8	Sat Jun 22 01:20:45 2019	(r349285)
+++ head/sbin/swapon/swapon.8	Sat Jun 22 03:16:01 2019	(r349286)
@@ -28,7 +28,7 @@
 .\"     @(#)swapon.8	8.1 (Berkeley) 6/5/93
 .\" $FreeBSD$
 .\"
-.Dd October 21, 2016
+.Dd June 21, 2019
 .Dt SWAPON 8
 .Os
 .Sh NAME
@@ -38,7 +38,7 @@
 .Nm swapon
 .Oo Fl F Ar fstab
 .Oc
-.Fl aLq | Ar
+.Fl aLq | E Ar
 .Nm swapoff
 .Oo Fl F Ar fstab
 .Oc
@@ -86,6 +86,11 @@ If the
 option is used,
 informational messages will not be
 written to standard output when a swap device is added.
+The
+.Fl E
+option causes each of following devices to receive a
+.Dv BIO_DELETE
+command to mark all blocks as unused.
 .Pp
 The
 .Nm swapoff

Modified: head/sbin/swapon/swapon.c
==============================================================================
--- head/sbin/swapon/swapon.c	Sat Jun 22 01:20:45 2019	(r349285)
+++ head/sbin/swapon/swapon.c	Sat Jun 22 03:16:01 2019	(r349286)
@@ -43,6 +43,7 @@ static char sccsid[] = "@(#)swapon.c	8.1 (Berkeley) 6/
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/disk.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/mdioctl.h>
@@ -77,7 +78,7 @@ static int run_cmd(int *, const char *, ...) __printfl
 
 static enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL;
 
-static int qflag;
+static int Eflag, qflag;
 
 int
 main(int argc, char **argv)
@@ -100,7 +101,7 @@ main(int argc, char **argv)
 	
 	doall = 0;
 	etc_fstab = NULL;
-	while ((ch = getopt(argc, argv, "AadghklLmqsUF:")) != -1) {
+	while ((ch = getopt(argc, argv, "AadEghklLmqsUF:")) != -1) {
 		switch(ch) {
 		case 'A':
 			if (which_prog == SWAPCTL) {
@@ -121,6 +122,12 @@ main(int argc, char **argv)
 			else
 				usage();
 			break;
+		case 'E':
+			if (which_prog == SWAPON)
+				Eflag = 2;
+			else
+				usage();
+			break;
 		case 'g':
 			hflag = 'G';
 			break;
@@ -182,8 +189,10 @@ main(int argc, char **argv)
 				    strstr(fsp->fs_mntops, "late") == NULL &&
 				    late != 0)
 					continue;
+				Eflag |= (strstr(fsp->fs_mntops, "trimonce") != NULL);
 				swfile = swap_on_off(fsp->fs_spec, 1,
 				    fsp->fs_mntops);
+				Eflag &= ~1;
 				if (swfile == NULL) {
 					ret = 1;
 					continue;
@@ -378,12 +387,22 @@ swap_on_geli_args(const char *mntops)
 					return (NULL);
 				}
 			} else if (strcmp(token, "notrim") == 0) {
+				if (Eflag) {
+					warn("Options \"notrim\" and "
+					    "\"trimonce\" conflict");
+					free(ops);
+					return (NULL);
+				}
 				Tflag = " -T ";
 			} else if (strcmp(token, "late") == 0) {
 				/* ignore known option */
 			} else if (strcmp(token, "noauto") == 0) {
 				/* ignore known option */
-			} else if (strcmp(token, "sw") != 0) {
+			} else if (strcmp(token, "sw") == 0) {
+				/* ignore known option */
+			} else if (strcmp(token, "trimonce") == 0) {
+				/* ignore known option */
+			} else {
 				warnx("Invalid option: %s", token);
 				free(ops);
 				return (NULL);
@@ -721,14 +740,42 @@ run_cmd(int *ofd, const char *cmdline, ...)
 	return (WEXITSTATUS(status));
 }
 
+static void
+swap_trim(const char *name)
+{
+	struct stat sb;
+	off_t ioarg[2], sz;
+	int fd;
+
+	fd = open(name, O_WRONLY);
+	if (fd < 0)
+		errx(1, "Cannot open %s", name);
+	if (fstat(fd, &sb) < 0)
+		errx(1, "Cannot stat %s", name);
+	if (S_ISREG(sb.st_mode))
+		sz = sb.st_size;
+	else if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) {
+		if (ioctl(fd, DIOCGMEDIASIZE, &sz) != 0)
+			err(1, "ioctl(DIOCGMEDIASIZE)");
+	} else
+		errx(1, "%s has an invalid file type", name);
+	ioarg[0] = 0;
+	ioarg[1] = sz;
+	if (ioctl(fd, DIOCGDELETE, ioarg) != 0)
+		warn("ioctl(DIOCGDELETE)");
+	close(fd);
+}
+
 static const char *
 swap_on_off_sfile(const char *name, int doingall)
 {
 	int error;
 
-	if (which_prog == SWAPON)
+	if (which_prog == SWAPON) {
+		if (Eflag)
+			swap_trim(name);
 		error = swapon(name);
-	else /* SWAPOFF */
+	} else /* SWAPOFF */
 		error = swapoff(name);
 
 	if (error == -1) {
@@ -759,6 +806,8 @@ usage(void)
 	fprintf(stderr, "usage: %s ", getprogname());
 	switch(orig_prog) {
 	case SWAPON:
+	    fprintf(stderr, "[-F fstab] -aLq | [-E] file ...\n");
+	    break;
 	case SWAPOFF:
 	    fprintf(stderr, "[-F fstab] -aLq | file ...\n");
 	    break;

Modified: head/share/man/man5/fstab.5
==============================================================================
--- head/share/man/man5/fstab.5	Sat Jun 22 01:20:45 2019	(r349285)
+++ head/share/man/man5/fstab.5	Sat Jun 22 03:16:01 2019	(r349286)
@@ -216,6 +216,12 @@ then the special file is made available as a piece of 
 space by the
 .Xr swapon 8
 command at the end of the system reboot procedure.
+For swap devices, the keyword
+.Dq trimonce
+triggers the delivery of a
+.Dv BIO_DELETE
+command to the device to mark
+all blocks as unused.
 For vnode-backed swap spaces,
 .Dq file
 is supported in the



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