public inbox for linux-block@vger.kernel.org
 help / color / mirror / Atom feed
* [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