dcavalca / rpms / util-linux

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