Blame SOURCES/0079-blkdiscard-backport-zeroout-support.patch

531551
From ca291153ff2c696696c1406aca6433aab6e412a1 Mon Sep 17 00:00:00 2001
531551
From: Karel Zak <kzak@redhat.com>
531551
Date: Fri, 24 Jun 2016 13:36:32 +0200
531551
Subject: [PATCH 79/84] blkdiscard: backport --zeroout support
531551
531551
The patch also includes upstream cleanups.
531551
531551
Upstream: http://github.com/karelzak/util-linux/commit/0e765365798c54d412e355798ad584a52035f228
531551
Upstream: http://github.com/karelzak/util-linux/commit/a3e91e26467a0f644ee568bb0b3d481591834015
531551
Upstream: http://github.com/karelzak/util-linux/commit/eeae448805c0eb2ef130a6ac301750706bb80420
531551
Upstream: http://github.com/karelzak/util-linux/commit/7154cc892688f3c58cbbcdc2055f2635c1d0ef5b
531551
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1327886
531551
Signed-off-by: Karel Zak <kzak@redhat.com>
531551
---
531551
 bash-completion/blkdiscard |   2 +-
531551
 sys-utils/blkdiscard.8     |   7 +--
531551
 sys-utils/blkdiscard.c     | 122 ++++++++++++++++++++++++++++++++++-----------
531551
 3 files changed, 98 insertions(+), 33 deletions(-)
531551
531551
diff --git a/bash-completion/blkdiscard b/bash-completion/blkdiscard
531551
index 310cdfb..fb3cb1e 100644
531551
--- a/bash-completion/blkdiscard
531551
+++ b/bash-completion/blkdiscard
531551
@@ -15,7 +15,7 @@ _blkdiscard_module()
531551
 	esac
531551
 	case $cur in
531551
 		-*)
531551
-			OPTS="--offset --length --secure --verbose --help --version"
531551
+			OPTS="--offset --length --secure --zeroout --verbose --help --version"
531551
 			COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
531551
 			return 0
531551
 			;;
531551
diff --git a/sys-utils/blkdiscard.8 b/sys-utils/blkdiscard.8
531551
index 5e094d4..71180e9 100644
531551
--- a/sys-utils/blkdiscard.8
531551
+++ b/sys-utils/blkdiscard.8
531551
@@ -1,15 +1,13 @@
531551
-.\" -*- nroff -*-
531551
 .TH BLKDISCARD 8 "July 2014" "util-linux" "System Administration"
531551
 .SH NAME
531551
 blkdiscard \- discard sectors on a device
531551
 .SH SYNOPSIS
531551
 .B blkdiscard
531551
+[options]
531551
 .RB [ \-o
531551
 .IR offset ]
531551
 .RB [ \-l
531551
 .IR length ]
531551
-.RB [ \-s ]
531551
-.RB [ \-v ]
531551
 .I device
531551
 .SH DESCRIPTION
531551
 .B blkdiscard
531551
@@ -59,6 +57,9 @@ Perform a secure discard.  A secure discard is the same as a regular discard
531551
 except that all copies of the discarded blocks that were possibly created by
531551
 garbage collection must also be erased.  This requires support from the device.
531551
 .TP
531551
+.BR \-z , " \-\-zeroout"
531551
+Zero-fill rather than discard.
531551
+.TP
531551
 .BR \-v , " \-\-verbose"
531551
 Display the aligned values of
531551
 .I offset
531551
diff --git a/sys-utils/blkdiscard.c b/sys-utils/blkdiscard.c
531551
index 92ca52a..0ba99ee 100644
531551
--- a/sys-utils/blkdiscard.c
531551
+++ b/sys-utils/blkdiscard.c
531551
@@ -44,43 +44,95 @@
531551
 #include "closestream.h"
531551
 
531551
 #ifndef BLKDISCARD
531551
-#define BLKDISCARD	_IO(0x12,119)
531551
+# define BLKDISCARD	_IO(0x12,119)
531551
 #endif
531551
 
531551
 #ifndef BLKSECDISCARD
531551
-#define BLKSECDISCARD	_IO(0x12,125)
531551
+# define BLKSECDISCARD	_IO(0x12,125)
531551
 #endif
531551
 
531551
-#define print_stats(path, stats) \
531551
-	printf(_("%s: Discarded %" PRIu64 " bytes from the " \
531551
-		 "offset %" PRIu64"\n"), path, stats[1], stats[0]);
531551
+#ifndef BLKZEROOUT
531551
+# define BLKZEROOUT	_IO(0x12,127)
531551
+#endif
531551
+
531551
+enum {
531551
+	ACT_DISCARD = 0,	/* default */
531551
+	ACT_ZEROOUT,
531551
+	ACT_SECURE
531551
+};
531551
+
531551
+/* RHEL: backport from upstream lib/monotonic.c */
531551
+static int gettime_monotonic(struct timeval *tv)
531551
+{
531551
+#ifdef CLOCK_MONOTONIC
531551
+	/* Can slew only by ntp and adjtime */
531551
+	int ret;
531551
+	struct timespec ts;
531551
+
531551
+# ifdef CLOCK_MONOTONIC_RAW
531551
+	/* Linux specific, can't slew */
531551
+	if (!(ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts))) {
531551
+# else
531551
+	if (!(ret = clock_gettime(CLOCK_MONOTONIC, &ts))) {
531551
+# endif
531551
+		tv->tv_sec = ts.tv_sec;
531551
+		tv->tv_usec = ts.tv_nsec / 1000;
531551
+	}
531551
+	return ret;
531551
+#else
531551
+	return gettimeofday(tv, NULL);
531551
+#endif
531551
+}
531551
+
531551
+static void print_stats(int act, char *path, uint64_t stats[])
531551
+{
531551
+	switch (act) {
531551
+	case ACT_ZEROOUT:
531551
+		printf(_("%s: Zero-filled %" PRIu64 " bytes from the offset %" PRIu64"\n"), \
531551
+			path, stats[1], stats[0]);
531551
+		break;
531551
+	case ACT_SECURE:
531551
+	case ACT_DISCARD:
531551
+		printf(_("%s: Discarded %" PRIu64 " bytes from the offset %" PRIu64"\n"), \
531551
+			path, stats[1], stats[0]);
531551
+		break;
531551
+	}
531551
+}
531551
 
531551
 static void __attribute__((__noreturn__)) usage(FILE *out)
531551
 {
531551
 	fputs(USAGE_HEADER, out);
531551
 	fprintf(out,
531551
 	      _(" %s [options] <device>\n"), program_invocation_short_name);
531551
+
531551
+	fputs(USAGE_SEPARATOR, out);
531551
+	fputs(_("Discard the content of sectors on a device.\n"), out);
531551
+
531551
 	fputs(USAGE_OPTIONS, out);
531551
-	fputs(_(" -o, --offset <num>  offset in bytes to discard from\n"
531551
-		" -l, --length <num>  length of bytes to discard from the offset\n"
531551
-		" -p, --step <num>    size of the discard iterations within the offset\n"
531551
-		" -s, --secure        perform secure discard\n"
531551
-		" -v, --verbose       print aligned length and offset\n"),
531551
-		out);
531551
+	fputs(_(" -o, --offset <num>  offset in bytes to discard from\n"), out);
531551
+	fputs(_(" -l, --length <num>  length of bytes to discard from the offset\n"), out);
531551
+	fputs(_(" -p, --step <num>    size of the discard iterations within the offset\n"), out);
531551
+	fputs(_(" -s, --secure        perform secure discard\n"), out);
531551
+	fputs(_(" -z, --zeroout       zero-fill rather than discard\n"), out);
531551
+	fputs(_(" -v, --verbose       print aligned length and offset\n"), out);
531551
+
531551
 	fputs(USAGE_SEPARATOR, out);
531551
 	fputs(USAGE_HELP, out);
531551
 	fputs(USAGE_VERSION, out);
531551
+
531551
 	fprintf(out, USAGE_MAN_TAIL("blkdiscard(8)"));
531551
 	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
531551
 }
531551
 
531551
+
531551
 int main(int argc, char **argv)
531551
 {
531551
 	char *path;
531551
-	int c, fd, verbose = 0, secure = 0, secsize;
531551
+	int c, fd, verbose = 0, secsize;
531551
 	uint64_t end, blksize, step, range[2], stats[2];
531551
 	struct stat sb;
531551
-	struct timespec now, last;
531551
+	struct timeval now, last;
531551
+	int act = ACT_DISCARD;
531551
 
531551
 	static const struct option longopts[] = {
531551
 	    { "help",      0, 0, 'h' },
531551
@@ -90,6 +142,7 @@ int main(int argc, char **argv)
531551
 	    { "step",      1, 0, 'p' },
531551
 	    { "secure",    0, 0, 's' },
531551
 	    { "verbose",   0, 0, 'v' },
531551
+	    { "zeroout",   0, 0, 'z' },
531551
 	    { NULL,        0, 0, 0 }
531551
 	};
531551
 
531551
@@ -102,7 +155,7 @@ int main(int argc, char **argv)
531551
 	range[1] = ULLONG_MAX;
531551
 	step = 0;
531551
 
531551
-	while ((c = getopt_long(argc, argv, "hVsvo:l:p:", longopts, NULL)) != -1) {
531551
+	while ((c = getopt_long(argc, argv, "hVsvo:l:p:z", longopts, NULL)) != -1) {
531551
 		switch(c) {
531551
 		case 'h':
531551
 			usage(stdout);
531551
@@ -123,11 +176,14 @@ int main(int argc, char **argv)
531551
 					_("failed to parse step"));
531551
 			break;
531551
 		case 's':
531551
-			secure = 1;
531551
+			act = ACT_SECURE;
531551
 			break;
531551
 		case 'v':
531551
 			verbose = 1;
531551
 			break;
531551
+		case 'z':
531551
+			act = ACT_ZEROOUT;
531551
+			break;
531551
 		default:
531551
 			usage(stderr);
531551
 			break;
531551
@@ -149,7 +205,7 @@ int main(int argc, char **argv)
531551
 		err(EXIT_FAILURE, _("cannot open %s"), path);
531551
 
531551
 	if (fstat(fd, &sb) == -1)
531551
-		err(EXIT_FAILURE, _("stat failed %s"), path);
531551
+		err(EXIT_FAILURE, _("stat of %s failed"), path);
531551
 	if (!S_ISBLK(sb.st_mode))
531551
 		errx(EXIT_FAILURE, _("%s: not a block device"), path);
531551
 
531551
@@ -178,35 +234,43 @@ int main(int argc, char **argv)
531551
 			 "to sector size %i"), path, range[1], secsize);
531551
 
531551
 	stats[0] = range[0], stats[1] = 0;
531551
-	clock_gettime(CLOCK_MONOTONIC, &last);
531551
+	gettime_monotonic(&last);
531551
 
531551
-	for (range[0] = range[0]; range[0] < end; range[0] += range[1]) {
531551
+	for (/* nothing */; range[0] < end; range[0] += range[1]) {
531551
 		if (range[0] + range[1] > end)
531551
 			range[1] = end - range[0];
531551
 
531551
-		if (secure) {
531551
+		switch (act) {
531551
+		case ACT_ZEROOUT:
531551
+			if (ioctl(fd, BLKZEROOUT, &range))
531551
+				 err(EXIT_FAILURE, _("%s: BLKZEROOUT ioctl failed"), path);
531551
+			break;
531551
+		case ACT_SECURE:
531551
 			if (ioctl(fd, BLKSECDISCARD, &range))
531551
 				err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path);
531551
-		} else {
531551
+			break;
531551
+		case ACT_DISCARD:
531551
 			if (ioctl(fd, BLKDISCARD, &range))
531551
 				err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path);
531551
+			break;
531551
 		}
531551
 
531551
-		/* reporting progress */
531551
+		stats[1] += range[1];
531551
+
531551
+		/* reporting progress at most once per second */
531551
 		if (verbose && step) {
531551
-			clock_gettime(CLOCK_MONOTONIC, &now;;
531551
-			if (last.tv_sec < now.tv_sec) {
531551
-				print_stats(path, stats);
531551
-				stats[0] = range[0], stats[1] = 0;
531551
+			gettime_monotonic(&now;;
531551
+			if (now.tv_sec > last.tv_sec &&
531551
+			    (now.tv_usec >= last.tv_usec || now.tv_sec > last.tv_sec + 1)) {
531551
+				print_stats(act, path, stats);
531551
+				stats[0] += stats[1], stats[1] = 0;
531551
 				last = now;
531551
 			}
531551
 		}
531551
-
531551
-		stats[1] += range[1];
531551
 	}
531551
 
531551
-	if (verbose)
531551
-		print_stats(path, stats);
531551
+	if (verbose && stats[1])
531551
+		print_stats(act, path, stats);
531551
 
531551
 	close(fd);
531551
 	return EXIT_SUCCESS;
531551
-- 
531551
2.7.4
531551