From 7154cc892688f3c58cbbcdc2055f2635c1d0ef5b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 24 Feb 2016 15:21:38 +0100 Subject: blkdiscard: add --zeroout (BLKZEROOUT ioctl) Requested-by: Yaniv Kaul Signed-off-by: Karel Zak --- sys-utils/blkdiscard.c | 59 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'sys-utils/blkdiscard.c') diff --git a/sys-utils/blkdiscard.c b/sys-utils/blkdiscard.c index f36e50492..ff2cee355 100644 --- a/sys-utils/blkdiscard.c +++ b/sys-utils/blkdiscard.c @@ -45,16 +45,37 @@ #include "monotonic.h" #ifndef BLKDISCARD -#define BLKDISCARD _IO(0x12,119) +# define BLKDISCARD _IO(0x12,119) #endif #ifndef BLKSECDISCARD -#define BLKSECDISCARD _IO(0x12,125) +# define BLKSECDISCARD _IO(0x12,125) #endif -#define print_stats(path, stats) \ - printf(_("%s: Discarded %" PRIu64 " bytes from the " \ - "offset %" PRIu64"\n"), path, stats[1], stats[0]); +#ifndef BLKZEROOUT +# define BLKZEROOUT _IO(0x12,127) +#endif + +enum { + ACT_DISCARD = 0, /* default */ + ACT_ZEROOUT, + ACT_SECURE +}; + +static void print_stats(int act, char *path, uint64_t stats[]) +{ + switch (act) { + case ACT_ZEROOUT: + printf(_("%s: Zero-filled %" PRIu64 " bytes from the offset %" PRIu64"\n"), \ + path, stats[1], stats[0]); + break; + case ACT_SECURE: + case ACT_DISCARD: + printf(_("%s: Discarded %" PRIu64 " bytes from the offset %" PRIu64"\n"), \ + path, stats[1], stats[0]); + break; + } +} static void __attribute__((__noreturn__)) usage(FILE *out) { @@ -70,6 +91,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out) " -l, --length length of bytes to discard from the offset\n" " -p, --step size of the discard iterations within the offset\n" " -s, --secure perform secure discard\n" + " -z, --zeroout zero-fill rather than discard\n" " -v, --verbose print aligned length and offset\n"), out); fputs(USAGE_SEPARATOR, out); @@ -79,13 +101,15 @@ static void __attribute__((__noreturn__)) usage(FILE *out) exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } + int main(int argc, char **argv) { char *path; - int c, fd, verbose = 0, secure = 0, secsize; + int c, fd, verbose = 0, secsize; uint64_t end, blksize, step, range[2], stats[2]; struct stat sb; struct timeval now, last; + int act = ACT_DISCARD; static const struct option longopts[] = { { "help", 0, 0, 'h' }, @@ -95,6 +119,7 @@ int main(int argc, char **argv) { "step", 1, 0, 'p' }, { "secure", 0, 0, 's' }, { "verbose", 0, 0, 'v' }, + { "zeroout", 0, 0, 'z' }, { NULL, 0, 0, 0 } }; @@ -107,7 +132,7 @@ int main(int argc, char **argv) range[1] = ULLONG_MAX; step = 0; - while ((c = getopt_long(argc, argv, "hVsvo:l:p:", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hVsvo:l:p:z", longopts, NULL)) != -1) { switch(c) { case 'h': usage(stdout); @@ -128,11 +153,14 @@ int main(int argc, char **argv) _("failed to parse step")); break; case 's': - secure = 1; + act = ACT_SECURE; break; case 'v': verbose = 1; break; + case 'z': + act = ACT_ZEROOUT; + break; default: usage(stderr); break; @@ -189,12 +217,19 @@ int main(int argc, char **argv) if (range[0] + range[1] > end) range[1] = end - range[0]; - if (secure) { + switch (act) { + case ACT_ZEROOUT: + if (ioctl(fd, BLKZEROOUT, &range)) + err(EXIT_FAILURE, _("%s: BLKZEROOUT ioctl failed"), path); + break; + case ACT_SECURE: if (ioctl(fd, BLKSECDISCARD, &range)) err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path); - } else { + break; + case ACT_DISCARD: if (ioctl(fd, BLKDISCARD, &range)) err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path); + break; } stats[1] += range[1]; @@ -204,7 +239,7 @@ int main(int argc, char **argv) gettime_monotonic(&now); if (now.tv_sec > last.tv_sec && (now.tv_usec >= last.tv_usec || now.tv_sec > last.tv_sec + 1)) { - print_stats(path, stats); + print_stats(act, path, stats); stats[0] += stats[1], stats[1] = 0; last = now; } @@ -212,7 +247,7 @@ int main(int argc, char **argv) } if (verbose && stats[1]) - print_stats(path, stats); + print_stats(act, path, stats); close(fd); return EXIT_SUCCESS; -- cgit v1.2.3-55-g7522