zbdioctl implements calls to zoned block devices ioctls that are not
supported currently by sys-utils blkzone utility, namely BLKGETZONESZ
and BLKGETNRZONES.

Reviewed-by: Chaitanya Kulkarni <[email protected]>
Signed-off-by: Shin'ichiro Kawasaki <[email protected]>
---
 src/.gitignore |  1 +
 src/Makefile   |  3 +-
 src/zbdioctl.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 src/zbdioctl.c

diff --git a/src/.gitignore b/src/.gitignore
index 8c95785..2108f56 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -6,3 +6,4 @@
 /nbdsetsize
 /sg/dxfer-from-dev
 /sg/syzkaller1
+/zbdioctl
diff --git a/src/Makefile b/src/Makefile
index c4094b4..5a0556f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -5,7 +5,8 @@ C_TARGETS := \
        sg/dxfer-from-dev \
        sg/syzkaller1 \
        nbdsetsize \
-       loop_change_fd
+       loop_change_fd \
+       zbdioctl
 
 CXX_TARGETS := \
        discontiguous-io
diff --git a/src/zbdioctl.c b/src/zbdioctl.c
new file mode 100644
index 0000000..1ea72e8
--- /dev/null
+++ b/src/zbdioctl.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-3.0+
+// Copyright (C) 2018 Western Digital Corporation or its affiliates.
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/blkzoned.h>
+#include <linux/types.h>
+
+#if !defined(BLKGETZONESZ) || !defined(BLKGETNRZONES)
+
+int main(int argc, char **argv)
+{
+       return EXIT_FAILURE;
+}
+
+#else
+
+struct request {
+       const char *name;
+       unsigned long code;
+} requests[] = {
+       { "-s", BLKGETZONESZ},
+       { "-n", BLKGETNRZONES},
+       { NULL, 0},
+};
+
+void usage(const char *progname)
+{
+       int i = 0;
+
+       fprintf(stderr, "usage: %s <request> <device file>\n", progname);
+       fprintf(stderr, "<request> can be:\n");
+       while (requests[i].name) {
+               fprintf(stderr, "\t%s\n", requests[i].name);
+               i++;
+       }
+       exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+       int i = 0, fd, ret;
+       unsigned int val;
+       unsigned long code = 0;
+
+       if (argc != 3)
+               usage(argv[0]);
+
+       while (requests[i].name) {
+               if (strcmp(argv[1], requests[i].name) == 0) {
+                       code = requests[i].code;
+                       break;
+               }
+               i++;
+       }
+       if (code == 0)
+               usage(argv[0]);
+
+       fd = open(argv[2], O_RDWR);
+       if (fd < 0) {
+               perror("open");
+               return EXIT_FAILURE;
+       }
+
+       ret = ioctl(fd, code, &val);
+       if (ret < 0) {
+               perror("ioctl");
+               close(fd);
+               return EXIT_FAILURE;
+       }
+
+       printf("%u\n", val);
+
+       close(fd);
+
+       return EXIT_SUCCESS;
+}
+
+#endif
+
-- 
2.20.1

Reply via email to