diff options
author | Federico Simoncelli | 2014-10-24 17:13:55 +0200 |
---|---|---|
committer | Karel Zak | 2014-10-27 09:16:49 +0100 |
commit | c472a7e35ae40652bdcf66c08a23bd50d48d1884 (patch) | |
tree | 8056c42170b27277b4f78afb3388e1acd4f083c3 /sys-utils/blkdiscard.c | |
parent | blkdiscard: fail on sector misalignment (diff) | |
download | kernel-qcow2-util-linux-c472a7e35ae40652bdcf66c08a23bd50d48d1884.tar.gz kernel-qcow2-util-linux-c472a7e35ae40652bdcf66c08a23bd50d48d1884.tar.xz kernel-qcow2-util-linux-c472a7e35ae40652bdcf66c08a23bd50d48d1884.zip |
blkdiscard: add support for steps and progress
Signed-off-by: Federico Simoncelli <fsimonce@redhat.com>
Diffstat (limited to 'sys-utils/blkdiscard.c')
-rw-r--r-- | sys-utils/blkdiscard.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/sys-utils/blkdiscard.c b/sys-utils/blkdiscard.c index 1504ee3b4..14d4b1979 100644 --- a/sys-utils/blkdiscard.c +++ b/sys-utils/blkdiscard.c @@ -49,6 +49,10 @@ #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]); + static void __attribute__((__noreturn__)) usage(FILE *out) { fputs(USAGE_HEADER, out); @@ -57,6 +61,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out) fputs(USAGE_OPTIONS, out); fputs(_(" -o, --offset <num> offset in bytes to discard from\n" " -l, --length <num> length of bytes to discard from the offset\n" + " -p, --step <num> size of the discard iterations within the offset\n" " -s, --secure perform secure discard\n" " -v, --verbose print aligned length and offset\n"), out); @@ -71,14 +76,16 @@ int main(int argc, char **argv) { char *path; int c, fd, verbose = 0, secure = 0, secsize; - uint64_t end, blksize, range[2]; + uint64_t end, blksize, step, range[2], stats[2]; struct stat sb; + struct timespec now, last; static const struct option longopts[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, { "offset", 1, 0, 'o' }, { "length", 1, 0, 'l' }, + { "step", 1, 0, 'p' }, { "secure", 0, 0, 's' }, { "verbose", 0, 0, 'v' }, { NULL, 0, 0, 0 } @@ -91,8 +98,9 @@ int main(int argc, char **argv) range[0] = 0; range[1] = ULLONG_MAX; + step = 0; - while ((c = getopt_long(argc, argv, "hVsvo:l:", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hVsvo:l:p:", longopts, NULL)) != -1) { switch(c) { case 'h': usage(stdout); @@ -108,6 +116,10 @@ int main(int argc, char **argv) range[0] = strtosize_or_err(optarg, _("failed to parse offset")); break; + case 'p': + step = strtosize_or_err(optarg, + _("failed to parse step")); + break; case 's': secure = 1; break; @@ -154,26 +166,45 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, _("%s: offset is greater than device size"), path); end = range[0] + range[1]; if (end < range[0] || end > blksize) - range[1] = blksize - range[0]; + end = blksize; + + range[1] = (step > 0) ? step : end - range[0]; /* check length alignment to the sector size */ if (range[1] % secsize) errx(EXIT_FAILURE, _("%s: length %" PRIu64 " is not aligned " "to sector size %i"), path, range[1], secsize); - if (secure) { - if (ioctl(fd, BLKSECDISCARD, &range)) - err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path); - } else { - if (ioctl(fd, BLKDISCARD, &range)) - err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path); + stats[0] = range[0], stats[1] = 0; + clock_gettime(CLOCK_MONOTONIC, &last); + + for (range[0] = range[0]; range[0] < end; range[0] += range[1]) { + if (range[0] + range[1] > end) + range[1] = end - range[0]; + + if (secure) { + if (ioctl(fd, BLKSECDISCARD, &range)) + err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path); + } else { + if (ioctl(fd, BLKDISCARD, &range)) + err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path); + } + + /* reporting progress */ + if (verbose && step) { + clock_gettime(CLOCK_MONOTONIC, &now); + if (last.tv_sec < now.tv_sec) { + print_stats(path, stats); + stats[0] = range[0], stats[1] = 0; + last = now; + } + } + + stats[1] += range[1]; } if (verbose) - /* TRANSLATORS: The standard value here is a very large number. */ - printf(_("%s: Discarded %" PRIu64 " bytes from the " - "offset %" PRIu64"\n"), path, - (uint64_t) range[1], (uint64_t) range[0]); + print_stats(path, stats); close(fd); return EXIT_SUCCESS; |