From: Aravind Ramesh <Aravind.Ramesh@xxxxxxx> Introduce blkzone open, close and finish commands, issuing BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl commands to open, close or finish a range of zones of a zoned block device. Since these three commands are similar to the existing zone reset command, the existing zone reset command implementation is changed into the generic blkzone_action() internal handler function for processing all zone actions. The BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl commands codes are defined in linux/blkzoned.h starting with kernel version 5.5. To ensure that the blkzone utility compiles even with older blkzoned.h kernel header versions, these ioctl commands are internally defined if the blkzoned.h header definition is not present. Execution of these commands on kernels older than 5.5 will result in a -ENOTTY error (missing ioctl). Signed-off-by: Aravind Ramesh <Aravind.Ramesh@xxxxxxx> Signed-off-by: Damien Le Moal <damien.lemoal@xxxxxxx> --- sys-utils/blkzone.8 | 27 +++++++++++++++++--- sys-utils/blkzone.c | 61 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/sys-utils/blkzone.8 b/sys-utils/blkzone.8 index 83d3dd7ce..f50e3f5df 100644 --- a/sys-utils/blkzone.8 +++ b/sys-utils/blkzone.8 @@ -55,10 +55,31 @@ x?:Reserved conditions (should not be reported) The command \fBblkzone reset\fP is used to reset one or more zones. Unlike .BR sg_reset_wp (8), this command operates from the block layer and can reset a range of zones. + +.SS open +The command \fBblkzone open\fP is used to explicitly open one or more zones. +Unlike +.BR sg_zone (8), +open action, this command operates from the block layer and can open a range +of zones. + +.SS close +The command \fBblkzone close\fP is used to close one or more zones. Unlike +.BR sg_zone (8), +close action, this command operates from the block layer and can close a range +of zones. + +.SS finish +The command \fBblkzone finish\fP is used to finish (transition to full condition) +one or more zones. Unlike +.BR sg_zone (8), +finish action, this command operates from the block layer and can finish a range +of zones. + .PP -By default, the command will operate from the zone at device -sector 0 and reset all zones. Options may be used to modify this behavior -as well as specify the operation to be performed on the zone, as explained below. +By default, the reset, open, close and finish commands will operate from the zone +at device sector 0 and operate on all zones. Options may be used to modify this +behavior as explained below. .SH OPTIONS The diff --git a/sys-utils/blkzone.c b/sys-utils/blkzone.c index 715f03fef..d2670f63e 100644 --- a/sys-utils/blkzone.c +++ b/sys-utils/blkzone.c @@ -44,14 +44,29 @@ #include "sysfs.h" #include "optutils.h" +/* + * These ioctls are defined in linux/blkzoned.h starting with kernel 5.5. + */ +#ifndef BLKOPENZONE +#define BLKOPENZONE _IOW(0x12, 134, struct blk_zone_range) +#endif +#ifndef BLKCLOSEZONE +#define BLKCLOSEZONE _IOW(0x12, 135, struct blk_zone_range) +#endif +#ifndef BLKFINISHZONE +#define BLKFINISHZONE _IOW(0x12, 136, struct blk_zone_range) +#endif + struct blkzone_control; static int blkzone_report(struct blkzone_control *ctl); -static int blkzone_reset(struct blkzone_control *ctl); +static int blkzone_action(struct blkzone_control *ctl); struct blkzone_command { const char *name; int (*handler)(struct blkzone_control *); + unsigned long ioctl_cmd; + const char *ioctl_name; const char *help; }; @@ -70,8 +85,36 @@ struct blkzone_control { }; static const struct blkzone_command commands[] = { - { "report", blkzone_report, N_("Report zone information about the given device") }, - { "reset", blkzone_reset, N_("Reset a range of zones.") } + { + "report", + blkzone_report, + 0, NULL, + N_("Report zone information about the given device") + }, + { + "reset", + blkzone_action, + BLKRESETZONE, "BLKRESETZONE", + N_("Reset a range of zones.") + }, + { + "open", + blkzone_action, + BLKOPENZONE, "BLKOPENZONE", + N_("Open a range of zones.") + }, + { + "close", + blkzone_action, + BLKCLOSEZONE, "BLKCLOSEZONE", + N_("Close a range of zones.") + }, + { + "finish", + blkzone_action, + BLKFINISHZONE, "BLKFINISHZONE", + N_("Set a range of zones to Full.") + } }; static const struct blkzone_command *name_to_command(const char *name) @@ -246,9 +289,9 @@ static int blkzone_report(struct blkzone_control *ctl) } /* - * blkzone reset + * blkzone reset, open, close, and finish. */ -static int blkzone_reset(struct blkzone_control *ctl) +static int blkzone_action(struct blkzone_control *ctl) { struct blk_zone_range za = { .sector = 0 }; unsigned long zonesize; @@ -288,11 +331,13 @@ static int blkzone_reset(struct blkzone_control *ctl) za.sector = ctl->offset; za.nr_sectors = zlen; - if (ioctl(fd, BLKRESETZONE, &za) == -1) - err(EXIT_FAILURE, _("%s: BLKRESETZONE ioctl failed"), ctl->devname); + if (ioctl(fd, ctl->command->ioctl_cmd, &za) == -1) + err(EXIT_FAILURE, _("%s: %s ioctl failed"), + ctl->devname, ctl->command->ioctl_name); else if (ctl->verbose) - printf(_("%s: successfully reset in range from %" PRIu64 ", to %" PRIu64), + printf(_("%s: successfull %s of zones in range from %" PRIu64 ", to %" PRIu64), ctl->devname, + ctl->command->name, ctl->offset, ctl->offset + zlen); close(fd); -- 2.25.1