* [PATCH v3 7/7] blk-zoned: implement ioctls
[not found] <1474888209-29445-8-git-send-email-damien.lemoal@hgst.com>
@ 2016-09-27 18:56 ` Shaun Tancheff
2016-09-27 21:23 ` Christoph Hellwig
0 siblings, 1 reply; 4+ messages in thread
From: Shaun Tancheff @ 2016-09-27 18:56 UTC (permalink / raw)
To: Jens Axboe
Cc: Shaun Tancheff, linux-block, linux-scsi, Christoph Hellwig,
Martin K . Petersen, Hannes Reinecke, Damien Le Moal,
shaun.tancheff
Adds the new BLKREPORTZONE and BLKRESETZONE ioctls for respectively
obtaining the zone configuration of a zoned block device and resetting
the write pointer of sequential zones of a zoned block device.
The BLKREPORTZONE ioctl maps directly to a single call of the function
blkdev_report_zones. The zone information result is passed as an array
of struct blk_zone identical to the structure used internally for
processing the REQ_OP_ZONE_REPORT operation. The BLKRESETZONE ioctl
maps to a single call of the blkdev_reset_zones function.
Signed-off-by: Shaun Tancheff <shaun.tancheff@seagate.com>
Signed-off-by: Damien Le Moal <damien.lemoal@hgst.com>
---
Changes since v2:
- Changed kzalloc() to kcalloc() per Christoph
- Added ioctl specific bits to uapi as blkzoned.h is now added in an earlier
patch.
block/blk-zoned.c | 93 +++++++++++++++++++++++++++++++++++++++++++
block/ioctl.c | 4 ++
include/linux/blkdev.h | 22 ++++++++++
include/uapi/linux/blkzoned.h | 40 +++++++++++++++++++
include/uapi/linux/fs.h | 4 ++
5 files changed, 163 insertions(+)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index bc4159d..91f7347 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -240,3 +240,96 @@ int blkdev_reset_zones(struct block_device *bdev,
return 0;
}
EXPORT_SYMBOL_GPL(blkdev_reset_zones);
+
+/**
+ * BLKREPORTZONE ioctl processing.
+ * Called from blkdev_ioctl.
+ */
+int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct request_queue *q;
+ struct blk_zone_report rep;
+ struct blk_zone *zones;
+ int ret;
+
+ if (!argp)
+ return -EINVAL;
+
+ q = bdev_get_queue(bdev);
+ if (!q)
+ return -ENXIO;
+
+ if (!blk_queue_is_zoned(q))
+ return -ENOTTY;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (copy_from_user(&rep, argp, sizeof(struct blk_zone_report)))
+ return -EFAULT;
+
+ if (!rep.nr_zones)
+ return -EINVAL;
+
+ zones = kcalloc(rep.nr_zones, sizeof(struct blk_zone), GFP_KERNEL);
+ if (!zones)
+ return -ENOMEM;
+
+ ret = blkdev_report_zones(bdev, rep.sector,
+ zones, &rep.nr_zones,
+ GFP_KERNEL);
+ if (ret)
+ goto out;
+
+ if (copy_to_user(argp, &rep, sizeof(struct blk_zone_report))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (rep.nr_zones) {
+ if (copy_to_user(argp + sizeof(struct blk_zone_report), zones,
+ sizeof(struct blk_zone) * rep.nr_zones))
+ ret = -EFAULT;
+ }
+
+ out:
+ kfree(zones);
+
+ return ret;
+}
+
+/**
+ * BLKRESETZONE ioctl processing.
+ * Called from blkdev_ioctl.
+ */
+int blkdev_reset_zones_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct request_queue *q;
+ struct blk_zone_range zrange;
+
+ if (!argp)
+ return -EINVAL;
+
+ q = bdev_get_queue(bdev);
+ if (!q)
+ return -ENXIO;
+
+ if (!blk_queue_is_zoned(q))
+ return -ENOTTY;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (!(mode & FMODE_WRITE))
+ return -EBADF;
+
+ if (copy_from_user(&zrange, argp, sizeof(struct blk_zone_range)))
+ return -EFAULT;
+
+ return blkdev_reset_zones(bdev, zrange.sector, zrange.nr_sectors,
+ GFP_KERNEL);
+}
diff --git a/block/ioctl.c b/block/ioctl.c
index ed2397f..448f78a 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -513,6 +513,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
BLKDEV_DISCARD_SECURE);
case BLKZEROOUT:
return blk_ioctl_zeroout(bdev, mode, arg);
+ case BLKREPORTZONE:
+ return blkdev_report_zones_ioctl(bdev, mode, cmd, arg);
+ case BLKRESETZONE:
+ return blkdev_reset_zones_ioctl(bdev, mode, cmd, arg);
case HDIO_GETGEO:
return blkdev_getgeo(bdev, argp);
case BLKRAGET:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 6316972..0a75285 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -315,6 +315,28 @@ extern int blkdev_report_zones(struct block_device *,
unsigned int *, gfp_t);
extern int blkdev_reset_zones(struct block_device *, sector_t,
sector_t, gfp_t);
+
+extern int blkdev_report_zones_ioctl(struct block_device *, fmode_t,
+ unsigned int, unsigned long);
+extern int blkdev_reset_zones_ioctl(struct block_device *, fmode_t,
+ unsigned int, unsigned long);
+
+#else /* CONFIG_BLK_DEV_ZONED */
+
+static inline int blkdev_report_zones_ioctl(struct block_device *bdev,
+ fmode_t mode, unsigned int cmd,
+ unsigned long arg)
+{
+ return -ENOTTY;
+}
+
+static inline int blkdev_reset_zones_ioctl(struct block_device *bdev,
+ fmode_t mode, unsigned int cmd,
+ unsigned long arg)
+{
+ return -ENOTTY;
+}
+
#endif /* CONFIG_BLK_DEV_ZONED */
struct request_queue {
diff --git a/include/uapi/linux/blkzoned.h b/include/uapi/linux/blkzoned.h
index a381721..40d1d7b 100644
--- a/include/uapi/linux/blkzoned.h
+++ b/include/uapi/linux/blkzoned.h
@@ -16,6 +16,7 @@
#define _UAPI_BLKZONED_H
#include <linux/types.h>
+#include <linux/ioctl.h>
/**
* enum blk_zone_type - Types of zones allowed in a zoned device.
@@ -100,4 +101,43 @@ struct blk_zone {
__u8 reserved[36];
};
+/**
+ * struct blk_zone_report - BLKREPORTZONE ioctl request/reply
+ *
+ * @sector: starting sector of report
+ * @nr_zones: IN maximum / OUT actual
+ * @reserved: padding to 16 byte alignment
+ * @zones: Space to hold @nr_zones @zones entries on reply.
+ *
+ * The array of at most @nr_zones must follow this structure in memory.
+ */
+struct blk_zone_report {
+ __u64 sector;
+ __u32 nr_zones;
+ __u8 reserved[4];
+ struct blk_zone zones[0];
+} __packed;
+
+/**
+ * struct blk_zone_range - BLKRESETZONE ioctl request
+ * @sector: starting sector of the first zone to issue reset write pointer
+ * @nr_sectors: Total number of sectors of 1 or more zones to reset
+ */
+struct blk_zone_range {
+ __u64 sector;
+ __u64 nr_sectors;
+};
+
+/**
+ * Zoned block device ioctl's:
+ *
+ * @BLKREPORTZONE: Get zone information. Takes a zone report as argument.
+ * The zone report will start from the zone containing the
+ * sector specified in the report request structure.
+ * @BLKRESETZONE: Reset the write pointer of the zones in the specified
+ * sector range. The sector range must be zone aligned.
+ */
+#define BLKREPORTZONE _IOWR(0x12, 130, struct blk_zone_report)
+#define BLKRESETZONE _IOW(0x12, 131, struct blk_zone_range)
+
#endif /* _UAPI_BLKZONED_H */
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 3b00f7c..e0fc7f0 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -222,6 +222,10 @@ struct fsxattr {
#define BLKSECDISCARD _IO(0x12,125)
#define BLKROTATIONAL _IO(0x12,126)
#define BLKZEROOUT _IO(0x12,127)
+/*
+ * A jump here: 130-131 are reserved for zoned block devices
+ * (see uapi/linux/blkzoned.h)
+ */
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
--
2.9.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 7/7] blk-zoned: implement ioctls
2016-09-27 18:56 ` [PATCH v3 7/7] blk-zoned: implement ioctls Shaun Tancheff
@ 2016-09-27 21:23 ` Christoph Hellwig
0 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2016-09-27 21:23 UTC (permalink / raw)
To: Shaun Tancheff
Cc: Jens Axboe, linux-block, linux-scsi, Christoph Hellwig,
Martin K . Petersen, Hannes Reinecke, Damien Le Moal,
shaun.tancheff
Damien, can you do a repost of the whole series with the
header reshuffled included? Except for that and the trivial
kcalloc bit the series looks fine to me:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 7/7] blk-zoned: implement ioctls
2016-09-28 1:22 [PATCH v3 0/7] ZBC / Zoned block device support Damien Le Moal
@ 2016-09-28 1:22 ` Damien Le Moal
2016-09-28 5:03 ` Martin K. Petersen
0 siblings, 1 reply; 4+ messages in thread
From: Damien Le Moal @ 2016-09-28 1:22 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-block, linux-scsi, Christoph Hellwig, Martin K . Petersen,
Hannes Reinecke, Shaun Tancheff, Damien Le Moal, Shaun Tancheff
From: Shaun Tancheff <shaun@tancheff.com>
Adds the new BLKREPORTZONE and BLKRESETZONE ioctls for respectively
obtaining the zone configuration of a zoned block device and resetting
the write pointer of sequential zones of a zoned block device.
The BLKREPORTZONE ioctl maps directly to a single call of the function
blkdev_report_zones. The zone information result is passed as an array
of struct blk_zone identical to the structure used internally for
processing the REQ_OP_ZONE_REPORT operation. The BLKRESETZONE ioctl
maps to a single call of the blkdev_reset_zones function.
Signed-off-by: Shaun Tancheff <shaun.tancheff@seagate.com>
Signed-off-by: Damien Le Moal <damien.lemoal@hgst.com>
---
block/blk-zoned.c | 93 +++++++++++++++++++++++++++++++++++++++++++
block/ioctl.c | 4 ++
include/linux/blkdev.h | 22 ++++++++++
include/uapi/linux/blkzoned.h | 40 +++++++++++++++++++
include/uapi/linux/fs.h | 4 ++
5 files changed, 163 insertions(+)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 7ebfc86..d354bea 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -255,3 +255,96 @@ int blkdev_reset_zones(struct block_device *bdev,
return 0;
}
EXPORT_SYMBOL_GPL(blkdev_reset_zones);
+
+/**
+ * BLKREPORTZONE ioctl processing.
+ * Called from blkdev_ioctl.
+ */
+int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct request_queue *q;
+ struct blk_zone_report rep;
+ struct blk_zone *zones;
+ int ret;
+
+ if (!argp)
+ return -EINVAL;
+
+ q = bdev_get_queue(bdev);
+ if (!q)
+ return -ENXIO;
+
+ if (!blk_queue_is_zoned(q))
+ return -ENOTTY;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (copy_from_user(&rep, argp, sizeof(struct blk_zone_report)))
+ return -EFAULT;
+
+ if (!rep.nr_zones)
+ return -EINVAL;
+
+ zones = kcalloc(rep.nr_zones, sizeof(struct blk_zone), GFP_KERNEL);
+ if (!zones)
+ return -ENOMEM;
+
+ ret = blkdev_report_zones(bdev, rep.sector,
+ zones, &rep.nr_zones,
+ GFP_KERNEL);
+ if (ret)
+ goto out;
+
+ if (copy_to_user(argp, &rep, sizeof(struct blk_zone_report))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (rep.nr_zones) {
+ if (copy_to_user(argp + sizeof(struct blk_zone_report), zones,
+ sizeof(struct blk_zone) * rep.nr_zones))
+ ret = -EFAULT;
+ }
+
+ out:
+ kfree(zones);
+
+ return ret;
+}
+
+/**
+ * BLKRESETZONE ioctl processing.
+ * Called from blkdev_ioctl.
+ */
+int blkdev_reset_zones_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct request_queue *q;
+ struct blk_zone_range zrange;
+
+ if (!argp)
+ return -EINVAL;
+
+ q = bdev_get_queue(bdev);
+ if (!q)
+ return -ENXIO;
+
+ if (!blk_queue_is_zoned(q))
+ return -ENOTTY;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (!(mode & FMODE_WRITE))
+ return -EBADF;
+
+ if (copy_from_user(&zrange, argp, sizeof(struct blk_zone_range)))
+ return -EFAULT;
+
+ return blkdev_reset_zones(bdev, zrange.sector, zrange.nr_sectors,
+ GFP_KERNEL);
+}
diff --git a/block/ioctl.c b/block/ioctl.c
index ed2397f..448f78a 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -513,6 +513,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
BLKDEV_DISCARD_SECURE);
case BLKZEROOUT:
return blk_ioctl_zeroout(bdev, mode, arg);
+ case BLKREPORTZONE:
+ return blkdev_report_zones_ioctl(bdev, mode, cmd, arg);
+ case BLKRESETZONE:
+ return blkdev_reset_zones_ioctl(bdev, mode, cmd, arg);
case HDIO_GETGEO:
return blkdev_getgeo(bdev, argp);
case BLKRAGET:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 6316972..0a75285 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -315,6 +315,28 @@ extern int blkdev_report_zones(struct block_device *,
unsigned int *, gfp_t);
extern int blkdev_reset_zones(struct block_device *, sector_t,
sector_t, gfp_t);
+
+extern int blkdev_report_zones_ioctl(struct block_device *, fmode_t,
+ unsigned int, unsigned long);
+extern int blkdev_reset_zones_ioctl(struct block_device *, fmode_t,
+ unsigned int, unsigned long);
+
+#else /* CONFIG_BLK_DEV_ZONED */
+
+static inline int blkdev_report_zones_ioctl(struct block_device *bdev,
+ fmode_t mode, unsigned int cmd,
+ unsigned long arg)
+{
+ return -ENOTTY;
+}
+
+static inline int blkdev_reset_zones_ioctl(struct block_device *bdev,
+ fmode_t mode, unsigned int cmd,
+ unsigned long arg)
+{
+ return -ENOTTY;
+}
+
#endif /* CONFIG_BLK_DEV_ZONED */
struct request_queue {
diff --git a/include/uapi/linux/blkzoned.h b/include/uapi/linux/blkzoned.h
index a381721..40d1d7b 100644
--- a/include/uapi/linux/blkzoned.h
+++ b/include/uapi/linux/blkzoned.h
@@ -16,6 +16,7 @@
#define _UAPI_BLKZONED_H
#include <linux/types.h>
+#include <linux/ioctl.h>
/**
* enum blk_zone_type - Types of zones allowed in a zoned device.
@@ -100,4 +101,43 @@ struct blk_zone {
__u8 reserved[36];
};
+/**
+ * struct blk_zone_report - BLKREPORTZONE ioctl request/reply
+ *
+ * @sector: starting sector of report
+ * @nr_zones: IN maximum / OUT actual
+ * @reserved: padding to 16 byte alignment
+ * @zones: Space to hold @nr_zones @zones entries on reply.
+ *
+ * The array of at most @nr_zones must follow this structure in memory.
+ */
+struct blk_zone_report {
+ __u64 sector;
+ __u32 nr_zones;
+ __u8 reserved[4];
+ struct blk_zone zones[0];
+} __packed;
+
+/**
+ * struct blk_zone_range - BLKRESETZONE ioctl request
+ * @sector: starting sector of the first zone to issue reset write pointer
+ * @nr_sectors: Total number of sectors of 1 or more zones to reset
+ */
+struct blk_zone_range {
+ __u64 sector;
+ __u64 nr_sectors;
+};
+
+/**
+ * Zoned block device ioctl's:
+ *
+ * @BLKREPORTZONE: Get zone information. Takes a zone report as argument.
+ * The zone report will start from the zone containing the
+ * sector specified in the report request structure.
+ * @BLKRESETZONE: Reset the write pointer of the zones in the specified
+ * sector range. The sector range must be zone aligned.
+ */
+#define BLKREPORTZONE _IOWR(0x12, 130, struct blk_zone_report)
+#define BLKRESETZONE _IOW(0x12, 131, struct blk_zone_range)
+
#endif /* _UAPI_BLKZONED_H */
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 3b00f7c..e0fc7f0 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -222,6 +222,10 @@ struct fsxattr {
#define BLKSECDISCARD _IO(0x12,125)
#define BLKROTATIONAL _IO(0x12,126)
#define BLKZEROOUT _IO(0x12,127)
+/*
+ * A jump here: 130-131 are reserved for zoned block devices
+ * (see uapi/linux/blkzoned.h)
+ */
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 7/7] blk-zoned: implement ioctls
2016-09-28 1:22 ` [PATCH v3 7/7] blk-zoned: implement ioctls Damien Le Moal
@ 2016-09-28 5:03 ` Martin K. Petersen
0 siblings, 0 replies; 4+ messages in thread
From: Martin K. Petersen @ 2016-09-28 5:03 UTC (permalink / raw)
To: Damien Le Moal
Cc: Jens Axboe, linux-block, linux-scsi, Christoph Hellwig,
Martin K . Petersen, Hannes Reinecke, Shaun Tancheff,
Shaun Tancheff
>>>>> "Damien" == Damien Le Moal <damien.lemoal@hgst.com> writes:
Damien> Adds the new BLKREPORTZONE and BLKRESETZONE ioctls for
Damien> respectively obtaining the zone configuration of a zoned block
Damien> device and resetting the write pointer of sequential zones of a
Damien> zoned block device.
Damien> The BLKREPORTZONE ioctl maps directly to a single call of the
Damien> function blkdev_report_zones. The zone information result is
Damien> passed as an array of struct blk_zone identical to the structure
Damien> used internally for processing the REQ_OP_ZONE_REPORT operation.
Damien> The BLKRESETZONE ioctl maps to a single call of the
Damien> blkdev_reset_zones function.
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-09-28 5:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1474888209-29445-8-git-send-email-damien.lemoal@hgst.com>
2016-09-27 18:56 ` [PATCH v3 7/7] blk-zoned: implement ioctls Shaun Tancheff
2016-09-27 21:23 ` Christoph Hellwig
2016-09-28 1:22 [PATCH v3 0/7] ZBC / Zoned block device support Damien Le Moal
2016-09-28 1:22 ` [PATCH v3 7/7] blk-zoned: implement ioctls Damien Le Moal
2016-09-28 5:03 ` Martin K. Petersen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).