Author: eugen
Date: Thu Mar 21 11:23:15 2019
New Revision: 345374
URL: https://svnweb.freebsd.org/changeset/base/345374

Log:
  MFC r345130,r345184: trim(8): add another safety net and more user-friendly
  error message in verbose mode.

Modified:
  stable/12/usr.sbin/trim/trim.c

Modified: stable/12/usr.sbin/trim/trim.c
==============================================================================
--- stable/12/usr.sbin/trim/trim.c      Thu Mar 21 10:51:36 2019        
(r345373)
+++ stable/12/usr.sbin/trim/trim.c      Thu Mar 21 11:23:15 2019        
(r345374)
@@ -2,7 +2,7 @@
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
  * Copyright (c) 2019 Eugene Grosbein <[email protected]>.
- * All rights reserved.
+ * Contains code written by Alan Somers <[email protected]>.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,12 +40,14 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sysexits.h>
 #include <unistd.h>
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+static bool    candelete(int fd);
 static off_t   getsize(const char *path);
 static int     opendev(const char *path, int flags);
 static int     trim(const char *path, off_t offset, off_t length, bool dryrun, 
bool verbose);
@@ -104,6 +106,23 @@ main(int argc, char **argv)
                        /* NOTREACHED */
                }
 
+       /*
+        * Safety net: do not allow mistakes like
+        *
+        *      trim -f /dev/da0 -r rfile
+        *
+        * This would trim whole device then error on non-existing file -r.
+        * Following check prevents this while allowing this form still:
+        *
+        *      trim -f -- /dev/da0 -r rfile
+        */
+       
+       if (strcmp(argv[optind-1], "--") != 0) {
+               for (ch = optind; ch < argc; ch++)
+                       if (argv[ch][0] == '-')
+                               usage(name);
+       }
+
        argv += optind;
        argc -= optind;
 
@@ -117,6 +136,19 @@ main(int argc, char **argv)
        return (error ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
+static bool
+candelete(int fd)
+{
+       struct diocgattr_arg arg;
+
+       strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name));
+       arg.len = sizeof(arg.value.i);
+       if (ioctl(fd, DIOCGATTR, &arg) == 0)
+               return (arg.value.i != 0);
+       else
+               return (false);
+}
+
 static int
 opendev(const char *path, int flags)
 {
@@ -193,9 +225,12 @@ trim(const char *path, off_t offset, off_t length, boo
        arg[1] = length;
 
        error = ioctl(fd, DIOCGDELETE, arg);
-       if (error < 0)
-               warn("ioctl(DIOCGDELETE) failed: %s", path);
-
+       if (error < 0) {
+               if (errno == EOPNOTSUPP && verbose && !candelete(fd))
+                       warnx("%s: TRIM/UNMAP not supported by driver", path);
+               else
+                       warn("ioctl(DIOCGDELETE) failed: %s", path);
+       }
        close(fd);
        return (error);
 }
_______________________________________________
[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