* [PATCH v3 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV
@ 2026-01-06 18:58 Yoav Cohen
2026-01-06 18:58 ` [PATCH v3 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen
2026-01-06 18:58 ` [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
0 siblings, 2 replies; 6+ messages in thread
From: Yoav Cohen @ 2026-01-06 18:58 UTC (permalink / raw)
To: Ming Lei, Jens Axboe, linux-block, csander
Cc: jholzman, omril, Yoav Cohen, 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
Changes since v1:
- Address Ming Lei’s comments in patch 2:
- Add a feature flag and some minor comments.
- Patch 1 unchanged, keeps Reviewed-by
Yoav Cohen (2):
ublk: make ublk_ctrl_stop_dev return void
ublk: add UBLK_CMD_TRY_STOP_DEV command
drivers/block/ublk_drv.c | 48 ++++++++++++++++++++++++++++++++---
include/uapi/linux/ublk_cmd.h | 9 ++++++-
2 files changed, 52 insertions(+), 5 deletions(-)
--
2.39.5 (Apple Git-154)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] ublk: make ublk_ctrl_stop_dev return void
2026-01-06 18:58 [PATCH v3 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen
@ 2026-01-06 18:58 ` Yoav Cohen
2026-01-06 18:58 ` [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
1 sibling, 0 replies; 6+ messages in thread
From: Yoav Cohen @ 2026-01-06 18:58 UTC (permalink / raw)
To: Ming Lei, Jens Axboe, linux-block, csander
Cc: jholzman, omril, Yoav Cohen, Yoav Cohen
This function always returns 0, so there is no need to return a value.
Signed-off-by: Yoav Cohen <yoav@nvidia.com>
Reviewed-by: Ming Lei <ming.lei@redhat.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] 6+ messages in thread
* [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command
2026-01-06 18:58 [PATCH v3 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen
2026-01-06 18:58 ` [PATCH v3 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen
@ 2026-01-06 18:58 ` Yoav Cohen
2026-01-06 19:27 ` Caleb Sander Mateos
1 sibling, 1 reply; 6+ messages in thread
From: Yoav Cohen @ 2026-01-06 18:58 UTC (permalink / raw)
To: Ming Lei, Jens Axboe, linux-block, csander
Cc: jholzman, omril, Yoav Cohen, 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.
Advertise UBLK_CMD_TRY_STOP_DEV support via UBLK_F_SAFE_STOP_DEV feature flag.
Signed-off-by: Yoav Cohen <yoav@nvidia.com>
---
drivers/block/ublk_drv.c | 42 ++++++++++++++++++++++++++++++++++-
include/uapi/linux/ublk_cmd.h | 9 +++++++-
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 2d5602ef05cc..9291eab4c31f 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)
@@ -73,7 +74,8 @@
| UBLK_F_AUTO_BUF_REG \
| UBLK_F_QUIESCE \
| UBLK_F_PER_IO_DAEMON \
- | UBLK_F_BUF_REG_OFF_DAEMON)
+ | UBLK_F_BUF_REG_OFF_DAEMON \
+ | UBLK_F_SAFE_STOP_DEV)
#define UBLK_F_ALL_RECOVERY_FLAGS (UBLK_F_USER_RECOVERY \
| UBLK_F_USER_RECOVERY_REISSUE \
@@ -239,6 +241,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[];
};
@@ -919,6 +923,9 @@ static int ublk_open(struct gendisk *disk, blk_mode_t mode)
return -EPERM;
}
+ if (ub->block_open)
+ return -EBUSY;
+
return 0;
}
@@ -3309,6 +3316,35 @@ 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 = 0;
+
+ disk = ublk_get_disk(ub);
+ if (!disk) {
+ return -ENODEV;
+ }
+
+ 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);
+ goto out;
+
+unlock:
+ mutex_unlock(&disk->open_mutex);
+out:
+ ublk_put_disk(disk);
+ return ret;
+}
+
static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
const struct ublksrv_ctrl_cmd *header)
{
@@ -3704,6 +3740,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 +3854,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..2b48c172542d 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
@@ -241,6 +242,12 @@
*/
#define UBLK_F_UPDATE_SIZE (1ULL << 10)
+/*
+ * The device supports the UBLK_CMD_TRY_STOP_DEV command, which
+ * allows stopping the device only if there are no openers.
+ */
+#define UBLK_F_SAFE_STOP_DEV (1ULL << 11)
+
/*
* request buffer is registered automatically to uring_cmd's io_uring
* context before delivering this io command to ublk server, meantime
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command
2026-01-06 18:58 ` [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
@ 2026-01-06 19:27 ` Caleb Sander Mateos
2026-01-06 19:40 ` Yoav Cohen
0 siblings, 1 reply; 6+ messages in thread
From: Caleb Sander Mateos @ 2026-01-06 19:27 UTC (permalink / raw)
To: Yoav Cohen; +Cc: Ming Lei, Jens Axboe, linux-block, jholzman, omril, Yoav Cohen
On Tue, Jan 6, 2026 at 10:59 AM Yoav Cohen <yoav@nvidia.com> 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.
>
> Advertise UBLK_CMD_TRY_STOP_DEV support via UBLK_F_SAFE_STOP_DEV feature flag.
>
> Signed-off-by: Yoav Cohen <yoav@nvidia.com>
> ---
> drivers/block/ublk_drv.c | 42 ++++++++++++++++++++++++++++++++++-
> include/uapi/linux/ublk_cmd.h | 9 +++++++-
> 2 files changed, 49 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index 2d5602ef05cc..9291eab4c31f 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)
> @@ -73,7 +74,8 @@
> | UBLK_F_AUTO_BUF_REG \
> | UBLK_F_QUIESCE \
> | UBLK_F_PER_IO_DAEMON \
> - | UBLK_F_BUF_REG_OFF_DAEMON)
> + | UBLK_F_BUF_REG_OFF_DAEMON \
> + | UBLK_F_SAFE_STOP_DEV)
Should also be added to the list of automatic feature flags in
ublk_ctrl_add_dev() (UBLK_F_CMD_IOCTL_ENCODE, ...,
UBLK_F_BUF_REG_OFF_DAEMON).
>
> #define UBLK_F_ALL_RECOVERY_FLAGS (UBLK_F_USER_RECOVERY \
> | UBLK_F_USER_RECOVERY_REISSUE \
> @@ -239,6 +241,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[];
> };
>
> @@ -919,6 +923,9 @@ static int ublk_open(struct gendisk *disk, blk_mode_t mode)
> return -EPERM;
> }
>
> + if (ub->block_open)
> + return -EBUSY;
> +
> return 0;
> }
>
> @@ -3309,6 +3316,35 @@ 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 = 0;
> +
> + disk = ublk_get_disk(ub);
> + if (!disk) {
> + return -ENODEV;
> + }
> +
> + 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);
> + goto out;
> +
> +unlock:
> + mutex_unlock(&disk->open_mutex);
> +out:
> + ublk_put_disk(disk);
> + return ret;
> +}
> +
> static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
> const struct ublksrv_ctrl_cmd *header)
> {
> @@ -3704,6 +3740,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 +3854,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..2b48c172542d 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
> @@ -241,6 +242,12 @@
> */
> #define UBLK_F_UPDATE_SIZE (1ULL << 10)
>
> +/*
> + * The device supports the UBLK_CMD_TRY_STOP_DEV command, which
> + * allows stopping the device only if there are no openers.
> + */
> +#define UBLK_F_SAFE_STOP_DEV (1ULL << 11)
This feature flag is already used for UBLK_F_AUTO_BUF_REG. Please use
bit 17 or higher, as bits up to 14 are already assigned and bits 15
and 16 are allocated by in-flight patch sets.
The feature flag should also be added to the list of known ublk
feature flags in cmd_dev_get_features() in
tools/testing/selftests/ublk/kublk.c.
Best,
Caleb
> +
> /*
> * request buffer is registered automatically to uring_cmd's io_uring
> * context before delivering this io command to ublk server, meantime
> --
> 2.39.5 (Apple Git-154)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command
2026-01-06 19:27 ` Caleb Sander Mateos
@ 2026-01-06 19:40 ` Yoav Cohen
2026-01-06 19:48 ` Caleb Sander Mateos
0 siblings, 1 reply; 6+ messages in thread
From: Yoav Cohen @ 2026-01-06 19:40 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Ming Lei, Jens Axboe, linux-block@vger.kernel.org, Jared Holzman,
Omri Levi, Yoav Cohen
On 06/01/2026 21:27, Caleb Sander Mateos wrote:
> External email: Use caution opening links or attachments
>
>
> On Tue, Jan 6, 2026 at 10:59 AM Yoav Cohen <yoav@nvidia.com> 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.
>>
>> Advertise UBLK_CMD_TRY_STOP_DEV support via UBLK_F_SAFE_STOP_DEV feature flag.
>>
>> Signed-off-by: Yoav Cohen <yoav@nvidia.com>
>> ---
>> drivers/block/ublk_drv.c | 42 ++++++++++++++++++++++++++++++++++-
>> include/uapi/linux/ublk_cmd.h | 9 +++++++-
>> 2 files changed, 49 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
>> index 2d5602ef05cc..9291eab4c31f 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)
>> @@ -73,7 +74,8 @@
>> | UBLK_F_AUTO_BUF_REG \
>> | UBLK_F_QUIESCE \
>> | UBLK_F_PER_IO_DAEMON \
>> - | UBLK_F_BUF_REG_OFF_DAEMON)
>> + | UBLK_F_BUF_REG_OFF_DAEMON \
>> + | UBLK_F_SAFE_STOP_DEV)
>
> Should also be added to the list of automatic feature flags in
> ublk_ctrl_add_dev() (UBLK_F_CMD_IOCTL_ENCODE, ...,
> UBLK_F_BUF_REG_OFF_DAEMON).
>
>>
>> #define UBLK_F_ALL_RECOVERY_FLAGS (UBLK_F_USER_RECOVERY \
>> | UBLK_F_USER_RECOVERY_REISSUE \
>> @@ -239,6 +241,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[];
>> };
>>
>> @@ -919,6 +923,9 @@ static int ublk_open(struct gendisk *disk, blk_mode_t mode)
>> return -EPERM;
>> }
>>
>> + if (ub->block_open)
>> + return -EBUSY;
>> +
>> return 0;
>> }
>>
>> @@ -3309,6 +3316,35 @@ 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 = 0;
>> +
>> + disk = ublk_get_disk(ub);
>> + if (!disk) {
>> + return -ENODEV;
>> + }
>> +
>> + 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);
>> + goto out;
>> +
>> +unlock:
>> + mutex_unlock(&disk->open_mutex);
>> +out:
>> + ublk_put_disk(disk);
>> + return ret;
>> +}
>> +
>> static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
>> const struct ublksrv_ctrl_cmd *header)
>> {
>> @@ -3704,6 +3740,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 +3854,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..2b48c172542d 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
>> @@ -241,6 +242,12 @@
>> */
>> #define UBLK_F_UPDATE_SIZE (1ULL << 10)
>>
>> +/*
>> + * The device supports the UBLK_CMD_TRY_STOP_DEV command, which
>> + * allows stopping the device only if there are no openers.
>> + */
>> +#define UBLK_F_SAFE_STOP_DEV (1ULL << 11)
>
> This feature flag is already used for UBLK_F_AUTO_BUF_REG. Please use
> bit 17 or higher, as bits up to 14 are already assigned and bits 15
> and 16 are allocated by in-flight patch sets.
>
> The feature flag should also be added to the list of known ublk
> feature flags in cmd_dev_get_features() in
> tools/testing/selftests/ublk/kublk.c.
>
> Best,
> Caleb
>
>> +
>> /*
>> * request buffer is registered automatically to uring_cmd's io_uring
>> * context before delivering this io command to ublk server, meantime
>> --
>> 2.39.5 (Apple Git-154)
>>
Thank you for the comments, on which branch should I rebased my changes on?
Thank you,
Yoav
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command
2026-01-06 19:40 ` Yoav Cohen
@ 2026-01-06 19:48 ` Caleb Sander Mateos
0 siblings, 0 replies; 6+ messages in thread
From: Caleb Sander Mateos @ 2026-01-06 19:48 UTC (permalink / raw)
To: Yoav Cohen
Cc: Ming Lei, Jens Axboe, linux-block@vger.kernel.org, Jared Holzman,
Omri Levi, Yoav Cohen
On Tue, Jan 6, 2026 at 11:40 AM Yoav Cohen <yoav@nvidia.com> wrote:
>
> On 06/01/2026 21:27, Caleb Sander Mateos wrote:
> > External email: Use caution opening links or attachments
> >
> >
> > On Tue, Jan 6, 2026 at 10:59 AM Yoav Cohen <yoav@nvidia.com> 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.
> >>
> >> Advertise UBLK_CMD_TRY_STOP_DEV support via UBLK_F_SAFE_STOP_DEV feature flag.
> >>
> >> Signed-off-by: Yoav Cohen <yoav@nvidia.com>
> >> ---
> >> drivers/block/ublk_drv.c | 42 ++++++++++++++++++++++++++++++++++-
> >> include/uapi/linux/ublk_cmd.h | 9 +++++++-
> >> 2 files changed, 49 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> >> index 2d5602ef05cc..9291eab4c31f 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)
> >> @@ -73,7 +74,8 @@
> >> | UBLK_F_AUTO_BUF_REG \
> >> | UBLK_F_QUIESCE \
> >> | UBLK_F_PER_IO_DAEMON \
> >> - | UBLK_F_BUF_REG_OFF_DAEMON)
> >> + | UBLK_F_BUF_REG_OFF_DAEMON \
> >> + | UBLK_F_SAFE_STOP_DEV)
> >
> > Should also be added to the list of automatic feature flags in
> > ublk_ctrl_add_dev() (UBLK_F_CMD_IOCTL_ENCODE, ...,
> > UBLK_F_BUF_REG_OFF_DAEMON).
> >
> >>
> >> #define UBLK_F_ALL_RECOVERY_FLAGS (UBLK_F_USER_RECOVERY \
> >> | UBLK_F_USER_RECOVERY_REISSUE \
> >> @@ -239,6 +241,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[];
> >> };
> >>
> >> @@ -919,6 +923,9 @@ static int ublk_open(struct gendisk *disk, blk_mode_t mode)
> >> return -EPERM;
> >> }
> >>
> >> + if (ub->block_open)
> >> + return -EBUSY;
> >> +
> >> return 0;
> >> }
> >>
> >> @@ -3309,6 +3316,35 @@ 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 = 0;
> >> +
> >> + disk = ublk_get_disk(ub);
> >> + if (!disk) {
> >> + return -ENODEV;
> >> + }
> >> +
> >> + 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);
> >> + goto out;
> >> +
> >> +unlock:
> >> + mutex_unlock(&disk->open_mutex);
> >> +out:
> >> + ublk_put_disk(disk);
> >> + return ret;
> >> +}
> >> +
> >> static int ublk_ctrl_get_dev_info(struct ublk_device *ub,
> >> const struct ublksrv_ctrl_cmd *header)
> >> {
> >> @@ -3704,6 +3740,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 +3854,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..2b48c172542d 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
> >> @@ -241,6 +242,12 @@
> >> */
> >> #define UBLK_F_UPDATE_SIZE (1ULL << 10)
> >>
> >> +/*
> >> + * The device supports the UBLK_CMD_TRY_STOP_DEV command, which
> >> + * allows stopping the device only if there are no openers.
> >> + */
> >> +#define UBLK_F_SAFE_STOP_DEV (1ULL << 11)
> >
> > This feature flag is already used for UBLK_F_AUTO_BUF_REG. Please use
> > bit 17 or higher, as bits up to 14 are already assigned and bits 15
> > and 16 are allocated by in-flight patch sets.
> >
> > The feature flag should also be added to the list of known ublk
> > feature flags in cmd_dev_get_features() in
> > tools/testing/selftests/ublk/kublk.c.
> >
> > Best,
> > Caleb
> >
> >> +
> >> /*
> >> * request buffer is registered automatically to uring_cmd's io_uring
> >> * context before delivering this io command to ublk server, meantime
> >> --
> >> 2.39.5 (Apple Git-154)
> >>
> Thank you for the comments, on which branch should I rebased my changes on?
I would use block-6.19. It looks like it has 1 additional ublk commit
on top of for-7.0/block. Feature flag bits 15 and 16 are used by the
following patch series, but they can be rebased on yours once it
lands:
UBLK_F_BATCH_IO:
https://lore.kernel.org/linux-block/20251202121917.1412280-11-ming.lei@redhat.com/T/#u
UBLK_F_NO_AUTO_PART_SCAN:
https://lore.kernel.org/linux-block/20251220095322.1527664-2-ming.lei@redhat.com/T/#u
UBLK_F_INTEGRITY:
https://lore.kernel.org/linux-block/20260106005752.3784925-4-csander@purestorage.com/T/#u
Best,
Caleb
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-01-06 19:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-06 18:58 [PATCH v3 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen
2026-01-06 18:58 ` [PATCH v3 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen
2026-01-06 18:58 ` [PATCH v3 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen
2026-01-06 19:27 ` Caleb Sander Mateos
2026-01-06 19:40 ` Yoav Cohen
2026-01-06 19:48 ` Caleb Sander Mateos
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox