From: Olaf Schmerse Date: Mon, 18 Oct 2021 13:42:29 +0000 (+0200) Subject: nvme: fail on busy namespace X-Git-Tag: v2.0-rc0~70^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=c5e1473d1b1963147add4a1994df35040c7f1226;p=users%2Fsagi%2Fnvme-cli.git nvme: fail on busy namespace To avoid formarting a busy namespace accidently a new function called open_exclusive() is implemented. Instead of opening it always it opens the device file in exclusive mode (O_EXCL). If this fails with the error EBUSY an error messages hints to the --force command line option. By calling nvme format with the --force option it will continue formating the namespace. This patch fixes issue: #1095 Signed-off-by: Olaf Schmerse --- diff --git a/nvme.c b/nvme.c index 25420775..d654493d 100644 --- a/nvme.c +++ b/nvme.c @@ -149,12 +149,12 @@ static bool is_blkdev(void) return S_ISBLK(nvme_stat.st_mode); } -static int open_dev(char *dev) +static int open_dev(char *dev, int flags) { int err, fd; devicename = basename(dev); - err = open(dev, O_RDONLY); + err = open(dev, flags); if (err < 0) goto perror; fd = err; @@ -185,7 +185,7 @@ static int check_arg_dev(int argc, char **argv) return 0; } -static int get_dev(int argc, char **argv) +static int get_dev(int argc, char **argv, int flags) { int ret; @@ -193,7 +193,7 @@ static int get_dev(int argc, char **argv) if (ret) return ret; - return open_dev(argv[optind]); + return open_dev(argv[optind], flags); } int parse_and_open(int argc, char **argv, const char *desc, @@ -205,13 +205,23 @@ int parse_and_open(int argc, char **argv, const char *desc, if (ret) return ret; - ret = get_dev(argc, argv); + ret = get_dev(argc, argv, O_RDONLY); if (ret < 0) argconfig_print_help(desc, opts); return ret; } +int open_exclusive(int argc, char **argv, int force) +{ + int flags = O_RDONLY; + + if (!force) + flags |= O_EXCL; + + return get_dev(argc, argv, flags); +} + enum nvme_print_flags validate_output_format(const char *format) { if (!format) @@ -3498,6 +3508,24 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu OPT_END() }; + err = argconfig_parse(argc, argv, desc, opts); + if (err) + goto ret; + + err = fd = open_exclusive(argc, argv, cfg.force); + if (fd < 0) { + if (errno == EBUSY) { + fprintf(stderr, "Failed to open %s.\n", + basename(argv[optind])); + fprintf(stderr, + "Namespace is currently busy.\n" + "Use the force [--force|-f] option to ignore that.\n"); + } else { + argconfig_print_help(desc, opts); + } + goto ret; + } + err = fd = parse_and_open(argc, argv, desc, opts); if (fd < 0) goto ret;