Author: dougm
Date: Fri Jul 12 02:03:43 2019
New Revision: 349930
URL: https://svnweb.freebsd.org/changeset/base/349930

Log:
  MFC r349286, r349293
  
  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.
  
  Remove #include <sys/types.h> to fix a style(9) violation.
  
  Assisted by: alc
  Release notes: yes
  Approved by: kib (mentor)

Modified:
  stable/12/sbin/swapon/swapon.8
  stable/12/sbin/swapon/swapon.c
  stable/12/share/man/man5/fstab.5
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sbin/swapon/swapon.8
==============================================================================
--- stable/12/sbin/swapon/swapon.8      Fri Jul 12 01:59:08 2019        
(r349929)
+++ stable/12/sbin/swapon/swapon.8      Fri Jul 12 02:03:43 2019        
(r349930)
@@ -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: stable/12/sbin/swapon/swapon.c
==============================================================================
--- stable/12/sbin/swapon/swapon.c      Fri Jul 12 01:59:08 2019        
(r349929)
+++ stable/12/sbin/swapon/swapon.c      Fri Jul 12 02:03:43 2019        
(r349930)
@@ -44,7 +44,7 @@ static char sccsid[] = "@(#)swapon.c  8.1 (Berkeley) 6/
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
-#include <sys/types.h>
+#include <sys/disk.h>
 #include <sys/mdioctl.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
@@ -77,7 +77,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 +100,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 +121,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 +188,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 +386,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 +739,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)) {
+               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 +805,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: stable/12/share/man/man5/fstab.5
==============================================================================
--- stable/12/share/man/man5/fstab.5    Fri Jul 12 01:59:08 2019        
(r349929)
+++ stable/12/share/man/man5/fstab.5    Fri Jul 12 02:03:43 2019        
(r349930)
@@ -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
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to