* [PATCH v2 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV @ 2026-01-04 8:48 Yoav Cohen 2026-01-04 8:48 ` [PATCH v2 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen 2026-01-04 8:48 ` [PATCH v2 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen 0 siblings, 2 replies; 5+ messages in thread From: Yoav Cohen @ 2026-01-04 8:48 UTC (permalink / raw) To: linux-block, csander, ming.lei; +Cc: jholzman, omril, 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 | 48 ++++++++++++++++++++++++++++++++--- include/uapi/linux/ublk_cmd.h | 3 ++- 2 files changed, 47 insertions(+), 4 deletions(-) -- 2.39.5 (Apple Git-154) ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] ublk: make ublk_ctrl_stop_dev return void 2026-01-04 8:48 [PATCH v2 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen @ 2026-01-04 8:48 ` Yoav Cohen 2026-01-06 14:14 ` Ming Lei 2026-01-04 8:48 ` [PATCH v2 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen 1 sibling, 1 reply; 5+ messages in thread From: Yoav Cohen @ 2026-01-04 8:48 UTC (permalink / raw) To: linux-block, csander, ming.lei; +Cc: jholzman, omril, 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] 5+ messages in thread
* Re: [PATCH v2 1/2] ublk: make ublk_ctrl_stop_dev return void 2026-01-04 8:48 ` [PATCH v2 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen @ 2026-01-06 14:14 ` Ming Lei 0 siblings, 0 replies; 5+ messages in thread From: Ming Lei @ 2026-01-06 14:14 UTC (permalink / raw) To: Yoav Cohen; +Cc: linux-block, csander, jholzman, omril On Sun, Jan 04, 2026 at 10:48:38AM +0200, Yoav Cohen wrote: > 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; Reviewed-by: Ming Lei <ming.lei@redhat.com> Thanks Ming ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command 2026-01-04 8:48 [PATCH v2 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen 2026-01-04 8:48 ` [PATCH v2 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen @ 2026-01-04 8:48 ` Yoav Cohen 2026-01-06 14:28 ` Ming Lei 1 sibling, 1 reply; 5+ messages in thread From: Yoav Cohen @ 2026-01-04 8:48 UTC (permalink / raw) To: linux-block, csander, ming.lei; +Cc: jholzman, omril, 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 | 42 +++++++++++++++++++++++++++++++++++ include/uapi/linux/ublk_cmd.h | 3 ++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 2d5602ef05cc..55a5ab11c1cd 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[]; }; @@ -919,6 +922,9 @@ static int ublk_open(struct gendisk *disk, blk_mode_t mode) return -EPERM; } + if (ub->block_open) + return -EBUSY; + return 0; } @@ -3309,6 +3315,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 +3742,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 +3856,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] 5+ messages in thread
* Re: [PATCH v2 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command 2026-01-04 8:48 ` [PATCH v2 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen @ 2026-01-06 14:28 ` Ming Lei 0 siblings, 0 replies; 5+ messages in thread From: Ming Lei @ 2026-01-06 14:28 UTC (permalink / raw) To: Yoav Cohen; +Cc: linux-block, csander, jholzman, omril On Sun, Jan 04, 2026 at 10:48:39AM +0200, 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 | 42 +++++++++++++++++++++++++++++++++++ > include/uapi/linux/ublk_cmd.h | 3 ++- > 2 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c > index 2d5602ef05cc..55a5ab11c1cd 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) This need a feature flag, such as UBLK_F_SAFE_STOP, which is set in ublk_ctrl_add_dev(), meantime document that UBLK_CMD_TRY_STOP_DEV is supported with this feature. > > #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[]; > }; > > @@ -919,6 +922,9 @@ static int ublk_open(struct gendisk *disk, blk_mode_t mode) > return -EPERM; > } > > + if (ub->block_open) > + return -EBUSY; > + > return 0; > } > > @@ -3309,6 +3315,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; -EINVAL is never used, it may save the line of `ret = 0` if it is initialized as 0. > + > + disk = ublk_get_disk(ub); > + if (!disk) { > + ret = -ENODEV; > + goto out; return -ENODEV; Thanks, Ming ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-01-06 14:28 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-04 8:48 [PATCH v2 0/2] ublk: introduce UBLK_CMD_TRY_STOP_DEV Yoav Cohen 2026-01-04 8:48 ` [PATCH v2 1/2] ublk: make ublk_ctrl_stop_dev return void Yoav Cohen 2026-01-06 14:14 ` Ming Lei 2026-01-04 8:48 ` [PATCH v2 2/2] ublk: add UBLK_CMD_TRY_STOP_DEV command Yoav Cohen 2026-01-06 14:28 ` Ming Lei
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox