* [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