trim(8): emit more user-friendly error message in verbose mode.

If underlying driver provides no TRIM/UNMAP support and operation fails
due to this reason, state it clearly in verbose mode (default)
instead of writing standard message that may be too cryptic for a user:

	trim: ioctl(DIOCGDELETE) failed: nda0: Operation not supported

Now it would write:

	trim: nda0: TRIM/UNMAP not supported by driver

But still use previous format including errno value for quiet mode.

Small candelete() function borrowed from diskinfo(8) code.
This function was committed by Alan Somers <asomers@FreeBSD.org>,
so give him some credit.

Reported by:	chuck
This commit is contained in:
Eugene Grosbein 2019-03-15 14:42:23 +00:00
parent a87407ff85
commit fa707ac77f

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2019 Eugene Grosbein <eugen@FreeBSD.org>.
* All rights reserved.
* Contains code written by Alan Somers <asomers@FreeBSD.org>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -47,6 +47,7 @@
#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);
@ -135,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)
{
@ -211,9 +225,12 @@ trim(const char *path, off_t offset, off_t length, bool dryrun, bool verbose)
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);
}