From: Damien Le Moal <dlemoal@kernel.org>
To: Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org, Christoph Hellwig <hch@lst.de>,
linux-scsi@vger.kernel.org,
"Martin K . Petersen" <martin.petersen@oracle.com>
Subject: [PATCH 3/7] block: add storage element management ioctls
Date: Mon, 5 Oct 2026 18:46:28 +0900 [thread overview]
Message-ID: <20261005094632.580753-4-dlemoal@kernel.org> (raw)
In-Reply-To: <20261005094632.580753-1-dlemoal@kernel.org>
Define the new ioctl commands BLKGETNRSTORELEMS, BLKREPORTSTORELEMS,
BLKREMOVESTORELEM, and BLKRESTORESTORELEMS to provide users accessing
zoned block devices directly with an interface to the storage elements
management operations of the block layer.
The ioctls BLKGETNRSTORELEMS and BLKREPORTSTORELEMS are defined to
respectively get the number of storage elements of a zoned device and to
get an array of struct blk_storage_element describing the current state of
the device storage elements.
The ioctl BLKREMOVESTORELEM can be used to remove (depopulate) a storage
element that has a degraded status (i.e. BLK_SE_STS_DEGRADED).
Finally, the BLKRESTORESTORELEMS ioctl interfaces with
bdev_restore_storage_elements() to restore the depopulated storage
elements of a zoned device.
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
block/blk-zoned.c | 114 ++++++++++++++++++++++++++++++++++
block/blk.h | 9 +++
block/ioctl.c | 5 ++
include/uapi/linux/blkzoned.h | 14 +++++
include/uapi/linux/fs.h | 1 +
5 files changed, 143 insertions(+)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index b713512f7d48..62b9cf21e9ad 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -19,6 +19,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
+#include <linux/uaccess.h>
#include <trace/events/block.h>
@@ -2794,6 +2795,69 @@ int bdev_report_storage_elements(struct block_device *bdev,
}
EXPORT_SYMBOL_GPL(bdev_report_storage_elements);
+static int blkdev_get_nr_storage_elements_ioctl(struct block_device *bdev,
+ void __user *argp)
+{
+ unsigned int nr_elements = 0;
+ int ret;
+
+ ret = bdev_report_storage_elements(bdev, &nr_elements, NULL);
+ if (ret)
+ return ret;
+
+ if (put_user(nr_elements, (unsigned int __user *)argp))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int blkdev_report_storage_elements_ioctl(struct block_device *bdev,
+ void __user *argp)
+{
+ struct blk_storage_elements_report rep;
+ struct blk_storage_element *elements;
+ unsigned int nr_elements;
+ unsigned long retc;
+ int ret;
+
+ if (!argp)
+ return -EINVAL;
+
+ if (copy_from_user(&rep, argp,
+ sizeof(struct blk_storage_elements_report)))
+ return -EFAULT;
+
+ if (!rep.nr_elements)
+ return -EINVAL;
+
+ nr_elements = rep.nr_elements;
+ elements = kzalloc_objs(struct blk_storage_element, nr_elements);
+ if (!elements)
+ return -ENOMEM;
+
+ ret = bdev_report_storage_elements(bdev, &nr_elements, elements);
+ if (ret)
+ goto free_elements;
+
+ retc = copy_to_user(argp + sizeof(struct blk_storage_elements_report),
+ elements,
+ sizeof(struct blk_storage_element) * nr_elements);
+ if (retc) {
+ ret = -EFAULT;
+ goto free_elements;
+ }
+
+ rep.nr_elements = nr_elements;
+ retc = copy_to_user(argp, &rep,
+ sizeof(struct blk_storage_elements_report));
+ if (retc)
+ ret = -EFAULT;
+
+free_elements:
+ kfree(elements);
+ return ret;
+}
+
/**
* bdev_remove_storage_element - Remove (depopulate) a storage element of a
* block device
@@ -2847,6 +2911,22 @@ int bdev_remove_storage_element(struct block_device *bdev,
}
EXPORT_SYMBOL_GPL(bdev_remove_storage_element);
+static int blkdev_remove_storage_element_ioctl(struct block_device *bdev,
+ blk_mode_t mode, void __user *argp)
+{
+ unsigned int element_id;
+
+ if (!(mode & BLK_OPEN_WRITE))
+ return -EBADF;
+ if (bdev_read_only(bdev))
+ return -EPERM;
+
+ if (get_user(element_id, (unsigned int __user *)argp))
+ return -EFAULT;
+
+ return bdev_remove_storage_element(bdev, element_id);
+}
+
/**
* bdev_restore_storage_elements - Restore all depopulated storage elements of a
* block device
@@ -2886,3 +2966,37 @@ int bdev_restore_storage_elements(struct block_device *bdev)
return blk_revalidate_disk_zones(disk);
}
EXPORT_SYMBOL_GPL(bdev_restore_storage_elements);
+
+static int blkdev_restore_storage_elements_ioctl(struct block_device *bdev,
+ blk_mode_t mode)
+{
+ if (!(mode & BLK_OPEN_WRITE))
+ return -EBADF;
+ if (bdev_read_only(bdev))
+ return -EPERM;
+
+ return bdev_restore_storage_elements(bdev);
+}
+
+int blkdev_zone_storage_elements_ioctl(struct block_device *bdev,
+ blk_mode_t mode, unsigned int cmd,
+ void __user *argp)
+{
+ if (!bdev_is_zoned(bdev) || !bdev->bd_disk->fops->se_ops)
+ return -ENOTTY;
+
+ switch (cmd) {
+ case BLKGETNRSTORELEMS:
+ return blkdev_get_nr_storage_elements_ioctl(bdev, argp);
+ case BLKREPORTSTORELEMS:
+ return blkdev_report_storage_elements_ioctl(bdev, argp);
+ case BLKREMOVESTORELEM:
+ return blkdev_remove_storage_element_ioctl(bdev, mode, argp);
+ case BLKRESTORESTORELEMS:
+ return blkdev_restore_storage_elements_ioctl(bdev, mode);
+ default:
+ break;
+ }
+
+ return -ENOTTY;
+}
diff --git a/block/blk.h b/block/blk.h
index c2d07347a3ad..274afb46a809 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -579,6 +579,9 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode,
unsigned int cmd, unsigned long arg);
bool bdev_zone_mgmt_allowed(struct block_device *bdev, sector_t sector);
bool bdev_zone_is_offline(struct block_device *bdev, sector_t sector);
+int blkdev_zone_storage_elements_ioctl(struct block_device *bdev,
+ blk_mode_t mode, unsigned int cmd,
+ void __user *argp);
#else /* CONFIG_BLK_DEV_ZONED */
static inline void disk_init_zone_resources(struct gendisk *disk)
{
@@ -631,6 +634,12 @@ static inline bool bdev_zone_is_offline(struct block_device *bdev,
{
return false;
}
+static inline int blkdev_zone_storage_elements_ioctl(struct block_device *bdev,
+ blk_mode_t mode, unsigned int cmd,
+ void __user *argp)
+{
+ return -ENOTTY;
+}
#endif /* CONFIG_BLK_DEV_ZONED */
struct block_device *bdev_alloc(struct gendisk *disk, u8 partno);
diff --git a/block/ioctl.c b/block/ioctl.c
index 64b4e6c0f696..ccf806c2e37d 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -679,6 +679,11 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
return put_uint(argp, bdev_zone_sectors(bdev));
case BLKGETNRZONES:
return put_uint(argp, bdev_nr_zones(bdev));
+ case BLKGETNRSTORELEMS:
+ case BLKREPORTSTORELEMS:
+ case BLKREMOVESTORELEM:
+ case BLKRESTORESTORELEMS:
+ return blkdev_zone_storage_elements_ioctl(bdev, mode, cmd, argp);
case BLKROGET:
return put_int(argp, bdev_read_only(bdev) != 0);
case BLKSSZGET: /* get block device logical block size */
diff --git a/include/uapi/linux/blkzoned.h b/include/uapi/linux/blkzoned.h
index 3a4bacfe7979..bd2c55d1a0d2 100644
--- a/include/uapi/linux/blkzoned.h
+++ b/include/uapi/linux/blkzoned.h
@@ -275,4 +275,18 @@ struct blk_storage_elements_report {
struct blk_storage_element elements[];
};
+/**
+ * Zoned block device storage element management ioctl's:
+ *
+ * @BLKGETNRSTORELEMS: Get the number of storage elements of the device.
+ * @BLKREPORTSTORELEMS: Get the device storage elements.
+ * @BLKREMOVESTORELEM: Remove (depopulate) one storage element of a device.
+ * @BLKRESTORESTORELEM: Restore (repopulate if possible) all storage elements
+ * that have been removed.
+ */
+#define BLKGETNRSTORELEMS _IOR(0x12, 143, __u32)
+#define BLKREPORTSTORELEMS _IOWR(0x12, 144, struct blk_storage_elements_report)
+#define BLKREMOVESTORELEM _IOW(0x12, 145, __u32)
+#define BLKRESTORESTORELEMS _IO(0x12, 146)
+
#endif /* _UAPI_BLKZONED_H */
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 34c6f219462a..8a979326aa7f 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -309,6 +309,7 @@ struct file_attr {
/* 130-136 and 142 are used by zoned block device ioctls (uapi/linux/blkzoned.h) */
/* 137-141 are used by blk-crypto ioctls (uapi/linux/blk-crypto.h) */
#define BLKTRACESETUP2 _IOWR(0x12, 142, struct blk_user_trace_setup2)
+/* 143-146 are used by storage element management for zoned block devices. */
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
--
2.55.0
next prev parent reply other threads:[~2026-10-05 9:46 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 9:46 [PATCH 0/7] Add support for storage element depopulation Damien Le Moal
2026-10-05 9:46 ` [PATCH 1/7] block: fail reads to offline zones early Damien Le Moal
2026-10-05 10:45 ` Hannes Reinecke
2026-10-05 9:46 ` [PATCH 2/7] block: introduce storage element management Damien Le Moal
2026-10-05 10:52 ` Hannes Reinecke
2026-10-05 22:15 ` kernel test robot
2026-10-05 9:46 ` Damien Le Moal [this message]
2026-10-05 11:09 ` [PATCH 3/7] block: add storage element management ioctls Hannes Reinecke
2026-10-05 9:46 ` [PATCH 4/7] zloop: add storage element emulation Damien Le Moal
2026-10-05 11:14 ` Hannes Reinecke
2026-10-05 9:46 ` [PATCH 5/7] zloop: add degrade_element control command Damien Le Moal
2026-10-05 11:17 ` Hannes Reinecke
2026-10-05 9:46 ` [PATCH 6/7] scsi: sd_zbc: always revalidate zones for disks supporting head depopulation Damien Le Moal
2026-10-05 11:19 ` Hannes Reinecke
2026-10-05 9:46 ` [PATCH 7/7] scsi: sd_zbc: define storage element management operations Damien Le Moal
2026-10-05 11:48 ` Hannes Reinecke
2026-10-05 20:48 ` kernel test robot
2026-10-05 21:41 ` kernel test robot
2026-10-05 11:13 ` [PATCH 0/7] Add support for storage element depopulation Hannes Reinecke
2026-10-07 7:14 ` Damien Le Moal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261005094632.580753-4-dlemoal@kernel.org \
--to=dlemoal@kernel.org \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox