* [PATCH 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV
@ 2025-12-30 12:51 Yoav Cohen
2025-12-30 12:51 ` [PATCH 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen
2025-12-30 12:51 ` [PATCH 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
0 siblings, 2 replies; 4+ messages in thread
From: Yoav Cohen @ 2025-12-30 12:51 UTC (permalink / raw)
To: ming.lei, linux-block; +Cc: jholzman, omril, ofer, Yoav Cohen
Hello,
This patch series introduces a new command for ublk device management.
The first patch changes `ublk_ctrl_stop_dev()` to return void, since it
always returned 0. This simplifies the API.
The second patch introduces `UBLK_CMD_TRY_STOP_DEV`, which stops the
device only if there are no active openers. Unlike the existing stop
command (`UBLK_CMD_STOP_DEV`), this command avoids disrupting active
users by returning -EBUSY if the device is busy.
These patches only introduce the new command and API simplification
without altering existing behavior for active users.
Yoav Cohen (2):
ublk: make ublk_ctrl_stop_dev return void
ublk: add UBLK_CMD_TRY_STOP_DEV command
drivers/block/ublk_drv.c | 45 ++++++++++++++++++++++++++++++++---
include/uapi/linux/ublk_cmd.h | 3 ++-
2 files changed, 44 insertions(+), 4 deletions(-)
--
2.39.5 (Apple Git-154)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] ublk: make ublk_ctrl_stop_dev return void
2025-12-30 12:51 [PATCH 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen
@ 2025-12-30 12:51 ` Yoav Cohen
2025-12-30 12:51 ` [PATCH 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
1 sibling, 0 replies; 4+ messages in thread
From: Yoav Cohen @ 2025-12-30 12:51 UTC (permalink / raw)
To: ming.lei, linux-block; +Cc: jholzman, omril, ofer, Yoav Cohen
This function always returns 0, so there is no need to return a value.
Signed-off-by: Yoav Cohen <yoav@nvidia.com>
---
drivers/block/ublk_drv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 837fedb02e0d..2d5602ef05cc 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -3304,10 +3304,9 @@ static inline void ublk_ctrl_cmd_dump(struct io_uring_cmd *cmd)
header->data[0], header->addr, header->len);
}
-static int ublk_ctrl_stop_dev(struct ublk_device *ub)
+static void ublk_ctrl_stop_dev(struct ublk_device *ub)
{
ublk_stop_dev(ub);
- return 0;
}
static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
@@ -3780,7 +3779,8 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
ret = ublk_ctrl_start_dev(ub, header);
break;
case UBLK_CMD_STOP_DEV:
- ret = ublk_ctrl_stop_dev(ub);
+ ublk_ctrl_stop_dev(ub);
+ ret = 0;
break;
case UBLK_CMD_GET_DEV_INFO:
case UBLK_CMD_GET_DEV_INFO2:
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command
2025-12-30 12:51 [PATCH 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen
2025-12-30 12:51 ` [PATCH 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen
@ 2025-12-30 12:51 ` Yoav Cohen
2025-12-30 13:20 ` Yoav Cohen
1 sibling, 1 reply; 4+ messages in thread
From: Yoav Cohen @ 2025-12-30 12:51 UTC (permalink / raw)
To: ming.lei, linux-block; +Cc: jholzman, omril, ofer, Yoav Cohen
This command is similar to UBLK_CMD_STOP_DEV, but it only stops the
device if there are no active openers for the ublk block device.
If the device is busy, the command returns -EBUSY instead of
disrupting active clients. This allows safe, non-destructive stopping.
Signed-off-by: Yoav Cohen <yoav@nvidia.com>
---
drivers/block/ublk_drv.c | 39 +++++++++++++++++++++++++++++++++++
include/uapi/linux/ublk_cmd.h | 3 ++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 2d5602ef05cc..7c4c920c35f7 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -54,6 +54,7 @@
#define UBLK_CMD_DEL_DEV_ASYNC _IOC_NR(UBLK_U_CMD_DEL_DEV_ASYNC)
#define UBLK_CMD_UPDATE_SIZE _IOC_NR(UBLK_U_CMD_UPDATE_SIZE)
#define UBLK_CMD_QUIESCE_DEV _IOC_NR(UBLK_U_CMD_QUIESCE_DEV)
+#define UBLK_CMD_TRY_STOP_DEV _IOC_NR(UBLK_U_CMD_TRY_STOP_DEV)
#define UBLK_IO_REGISTER_IO_BUF _IOC_NR(UBLK_U_IO_REGISTER_IO_BUF)
#define UBLK_IO_UNREGISTER_IO_BUF _IOC_NR(UBLK_U_IO_UNREGISTER_IO_BUF)
@@ -239,6 +240,8 @@ struct ublk_device {
struct delayed_work exit_work;
struct work_struct partition_scan_work;
+ bool block_open; /* protected by open_mutex */
+
struct ublk_queue *queues[];
};
@@ -3309,6 +3312,38 @@ static void ublk_ctrl_stop_dev(struct ublk_device *ub)
ublk_stop_dev(ub);
}
+static int ublk_ctrl_try_stop_dev(struct ublk_device *ub)
+{
+ struct gendisk *disk;
+ int ret = -EINVAL;
+
+ disk = ublk_get_disk(ub);
+ if (!disk) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ mutex_lock(&disk->open_mutex);
+ if (disk_openers(disk) > 0) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+ ub->block_open = true;
+ /* release open_mutex as del_gendisk() will reacquire it */
+ mutex_unlock(&disk->open_mutex);
+
+ ublk_ctrl_stop_dev(ub);
+ ret = 0;
+ goto put_disk;
+
+unlock:
+ mutex_unlock(&disk->open_mutex);
+put_disk:
+ ublk_put_disk(disk);
+out:
+ return ret;
+}
+
static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
const struct ublksrv_ctrl_cmd *header)
{
@@ -3704,6 +3739,7 @@ static int ublk_ctrl_uring_cmd_permission(struct ublk_device *ub,
case UBLK_CMD_END_USER_RECOVERY:
case UBLK_CMD_UPDATE_SIZE:
case UBLK_CMD_QUIESCE_DEV:
+ case UBLK_CMD_TRY_STOP_DEV:
mask = MAY_READ | MAY_WRITE;
break;
default:
@@ -3817,6 +3853,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
case UBLK_CMD_QUIESCE_DEV:
ret = ublk_ctrl_quiesce_dev(ub, header);
break;
+ case UBLK_CMD_TRY_STOP_DEV:
+ ret = ublk_ctrl_try_stop_dev(ub);
+ break;
default:
ret = -EOPNOTSUPP;
break;
diff --git a/include/uapi/linux/ublk_cmd.h b/include/uapi/linux/ublk_cmd.h
index ec77dabba45b..bb191d0afff7 100644
--- a/include/uapi/linux/ublk_cmd.h
+++ b/include/uapi/linux/ublk_cmd.h
@@ -55,7 +55,8 @@
_IOWR('u', 0x15, struct ublksrv_ctrl_cmd)
#define UBLK_U_CMD_QUIESCE_DEV \
_IOWR('u', 0x16, struct ublksrv_ctrl_cmd)
-
+#define UBLK_U_CMD_TRY_STOP_DEV \
+ _IOWR('u', 0x17, struct ublksrv_ctrl_cmd)
/*
* 64bits are enough now, and it should be easy to extend in case of
* running out of feature flags
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command
2025-12-30 12:51 ` [PATCH 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
@ 2025-12-30 13:20 ` Yoav Cohen
0 siblings, 0 replies; 4+ messages in thread
From: Yoav Cohen @ 2025-12-30 13:20 UTC (permalink / raw)
To: ming.lei@redhat.com, linux-block@vger.kernel.org
Cc: Jared Holzman, Omri Levi, Ofer Oshri
On 30/12/2025 14:51, Yoav Cohen wrote:
> This command is similar to UBLK_CMD_STOP_DEV, but it only stops the
> device if there are no active openers for the ublk block device.
> If the device is busy, the command returns -EBUSY instead of
> disrupting active clients. This allows safe, non-destructive stopping.
>
> Signed-off-by: Yoav Cohen <yoav@nvidia.com>
> ---
> drivers/block/ublk_drv.c | 39 +++++++++++++++++++++++++++++++++++
> include/uapi/linux/ublk_cmd.h | 3 ++-
> 2 files changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index 2d5602ef05cc..7c4c920c35f7 100644
> --- a/drivers/block/ublk_drv.c
> +++ b/drivers/block/ublk_drv.c
> @@ -54,6 +54,7 @@
> #define UBLK_CMD_DEL_DEV_ASYNC _IOC_NR(UBLK_U_CMD_DEL_DEV_ASYNC)
> #define UBLK_CMD_UPDATE_SIZE _IOC_NR(UBLK_U_CMD_UPDATE_SIZE)
> #define UBLK_CMD_QUIESCE_DEV _IOC_NR(UBLK_U_CMD_QUIESCE_DEV)
> +#define UBLK_CMD_TRY_STOP_DEV _IOC_NR(UBLK_U_CMD_TRY_STOP_DEV)
>
> #define UBLK_IO_REGISTER_IO_BUF _IOC_NR(UBLK_U_IO_REGISTER_IO_BUF)
> #define UBLK_IO_UNREGISTER_IO_BUF _IOC_NR(UBLK_U_IO_UNREGISTER_IO_BUF)
> @@ -239,6 +240,8 @@ struct ublk_device {
> struct delayed_work exit_work;
> struct work_struct partition_scan_work;
>
> + bool block_open; /* protected by open_mutex */
> +
> struct ublk_queue *queues[];
> };
>
> @@ -3309,6 +3312,38 @@ static void ublk_ctrl_stop_dev(struct ublk_device *ub)
> ublk_stop_dev(ub);
> }
>
> +static int ublk_ctrl_try_stop_dev(struct ublk_device *ub)
> +{
> + struct gendisk *disk;
> + int ret = -EINVAL;
> +
> + disk = ublk_get_disk(ub);
> + if (!disk) {
> + ret = -ENODEV;
> + goto out;
> + }
> +
> + mutex_lock(&disk->open_mutex);
> + if (disk_openers(disk) > 0) {
> + ret = -EBUSY;
> + goto unlock;
> + }
> + ub->block_open = true;
> + /* release open_mutex as del_gendisk() will reacquire it */
> + mutex_unlock(&disk->open_mutex);
> +
> + ublk_ctrl_stop_dev(ub);
> + ret = 0;
> + goto put_disk;
> +
> +unlock:
> + mutex_unlock(&disk->open_mutex);
> +put_disk:
> + ublk_put_disk(disk);
> +out:
> + return ret;
> +}
> +
> static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
> const struct ublksrv_ctrl_cmd *header)
> {
> @@ -3704,6 +3739,7 @@ static int ublk_ctrl_uring_cmd_permission(struct ublk_device *ub,
> case UBLK_CMD_END_USER_RECOVERY:
> case UBLK_CMD_UPDATE_SIZE:
> case UBLK_CMD_QUIESCE_DEV:
> + case UBLK_CMD_TRY_STOP_DEV:
> mask = MAY_READ | MAY_WRITE;
> break;
> default:
> @@ -3817,6 +3853,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
> case UBLK_CMD_QUIESCE_DEV:
> ret = ublk_ctrl_quiesce_dev(ub, header);
> break;
> + case UBLK_CMD_TRY_STOP_DEV:
> + ret = ublk_ctrl_try_stop_dev(ub);
> + break;
> default:
> ret = -EOPNOTSUPP;
> break;
> diff --git a/include/uapi/linux/ublk_cmd.h b/include/uapi/linux/ublk_cmd.h
> index ec77dabba45b..bb191d0afff7 100644
> --- a/include/uapi/linux/ublk_cmd.h
> +++ b/include/uapi/linux/ublk_cmd.h
> @@ -55,7 +55,8 @@
> _IOWR('u', 0x15, struct ublksrv_ctrl_cmd)
> #define UBLK_U_CMD_QUIESCE_DEV \
> _IOWR('u', 0x16, struct ublksrv_ctrl_cmd)
> -
> +#define UBLK_U_CMD_TRY_STOP_DEV \
> + _IOWR('u', 0x17, struct ublksrv_ctrl_cmd)
> /*
> * 64bits are enough now, and it should be easy to extend in case of
> * running out of feature flags
Sorry but this is missing a check for ub->block_open in ublk_open - I
will submit it as part of the V2
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-12-30 13:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-30 12:51 [PATCH 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen
2025-12-30 12:51 ` [PATCH 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen
2025-12-30 12:51 ` [PATCH 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
2025-12-30 13:20 ` Yoav Cohen
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).