diff options
Diffstat (limited to 'toys')
-rw-r--r-- | toys/pending/blkdiscard.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/toys/pending/blkdiscard.c b/toys/pending/blkdiscard.c new file mode 100644 index 00000000..1f0c09cd --- /dev/null +++ b/toys/pending/blkdiscard.c @@ -0,0 +1,78 @@ +/* blkdiscard - discard device sectors + * + * Copyright 2020 Patrick Oppenlander <patrick.oppenlander@gmail.com> + * + * See https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/sys-utils/blkdiscard.8 + * + * These options are not supported: + * -v, --verbose + * -p, --step + * -V, --version + * + * Size parsing does not match util-linux where MB, GB, TB are multiples of + * 1000 and MiB, TiB, GiB are multipes of 1024. + +USE_BLKDISCARD(NEWTOY(blkdiscard, "<1>1f(force)l(length):o(offset):s(secure)z(zeroout)", TOYFLAG_BIN)) + +config BLKDISCARD + bool "blkdiscard" + default n + help + usage: blkdiscard [options] device + + Discard device sectors. + + -o, --offset OFF Byte offset from which to start discarding + -l, --length LEN Number of bytes to discard + -s, --secure Perform secure discard + -z, --zeroout Zero-fill rather than discard + -f, --force Disable checking for mounted filesystem + + By default OFF is zero and LEN is the device size meaning that the entire + device will be discarded. + + OFF and LEN must be aligned to the device sector size. + + WARNING: All discarded data will be permanently lost! +*/ + +#define FOR_blkdiscard +#include "toys.h" + +#include <linux/fs.h> + +GLOBALS( + char *offset, *length; +) + +void blkdiscard_main(void) +{ + int fd, req = BLKDISCARD; + uint64_t off = 0, len; + + fd = xopen(toys.optargs[0], O_WRONLY | (FLAG(f) ? 0 : O_EXCL)); + + if (FLAG(o)) off = atolx_range(TT.offset, 0, LLONG_MAX); + + if (FLAG(l)) len = atolx_range(TT.length, 0, LLONG_MAX); + else { + if (ioctl(fd, BLKGETSIZE64, &len) < 0) { + perror_msg("ioctl %x", (int)BLKGETSIZE64); + goto out; + } + len -= off; + } + + if (FLAG(s) && FLAG(z)) { + error_msg("secure and zeroout are mutually exclusive"); + goto out; + } + if (FLAG(s)) req = BLKSECDISCARD; + if (FLAG(z)) req = BLKZEROOUT; + + if (ioctl(fd, req, (uint64_t[]){off, len}) < 0) + perror_msg("ioctl %x", req); + +out: + if (CFG_TOYBOX_FREE) close(fd); +} |