blob: 0ecb867029aaf65a10a186e5fb73bd08dc55bb33 [file] [log] [blame]
From 34fed3ff1740aded9c2aae6b5d67a4eb696f738e Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 9 Jan 2020 11:03:51 +0100
Subject: [PATCH] blkdiscard: use O_EXCL, add --force
Let's make it more robust and safe. O_EXCL is an elegant way how to avoid
unwanted discard on mounted device.
Addresses: https://github.com/karelzak/util-linux/issues/915
Signed-off-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Carlos Santos <unixmania@gmail.com>
---
sys-utils/blkdiscard.8 | 5 +++++
sys-utils/blkdiscard.c | 11 ++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/sys-utils/blkdiscard.8 b/sys-utils/blkdiscard.8
index 1f3a32be9..98c6f36a9 100644
--- a/sys-utils/blkdiscard.8
+++ b/sys-utils/blkdiscard.8
@@ -36,6 +36,11 @@ MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is
optional, e.g., "K" has the same meaning as "KiB") or the suffixes
KB (=1000), MB (=1000*1000), and so on for GB, TB, PB, EB, ZB and YB.
.TP
+.BR \-f , " \-\-force"
+Disable all checking. Since v2.36 the block device is open in exclusive mode (O_EXCL)
+by default to avoid collision with mounted filesystem or another kernel subsystem.
+The force option disables the exclusive access mode.
+.TP
.BR \-o , " \-\-offset \fIoffset"
Byte offset into the device from which to start discarding. The provided value
will be aligned to the device sector size. The default value is zero.
diff --git a/sys-utils/blkdiscard.c b/sys-utils/blkdiscard.c
index f9ba5e468..589974f9c 100644
--- a/sys-utils/blkdiscard.c
+++ b/sys-utils/blkdiscard.c
@@ -88,6 +88,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_("Discard the content of sectors on a device.\n"), out);
fputs(USAGE_OPTIONS, out);
+ fputs(_(" -f, --force disable all checking\n"), out);
fputs(_(" -o, --offset <num> offset in bytes to discard from\n"), out);
fputs(_(" -l, --length <num> length of bytes to discard from the offset\n"), out);
fputs(_(" -p, --step <num> size of the discard iterations within the offset\n"), out);
@@ -106,7 +107,7 @@ static void __attribute__((__noreturn__)) usage(void)
int main(int argc, char **argv)
{
char *path;
- int c, fd, verbose = 0, secsize;
+ int c, fd, verbose = 0, secsize, force = 0;
uint64_t end, blksize, step, range[2], stats[2];
struct stat sb;
struct timeval now, last;
@@ -116,6 +117,7 @@ int main(int argc, char **argv)
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "offset", required_argument, NULL, 'o' },
+ { "force", no_argument, NULL, 'f' },
{ "length", required_argument, NULL, 'l' },
{ "step", required_argument, NULL, 'p' },
{ "secure", no_argument, NULL, 's' },
@@ -133,8 +135,11 @@ int main(int argc, char **argv)
range[1] = ULLONG_MAX;
step = 0;
- while ((c = getopt_long(argc, argv, "hVsvo:l:p:z", longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "hfVsvo:l:p:z", longopts, NULL)) != -1) {
switch(c) {
+ case 'f':
+ force = 1;
+ break;
case 'l':
range[1] = strtosize_or_err(optarg,
_("failed to parse length"));
@@ -176,7 +181,7 @@ int main(int argc, char **argv)
errtryhelp(EXIT_FAILURE);
}
- fd = open(path, O_WRONLY);
+ fd = open(path, O_WRONLY | (force ? 0 : O_EXCL));
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), path);
--
2.18.2