Userspace may support more features or new added flags, but the driver side can be old, so make sure correct flags(features) returned to userpsace, then userspace can work as expected. Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- drivers/block/ublk_drv.c | 22 +++++++++++++++++++--- include/uapi/linux/ublk_cmd.h | 11 +++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index d03563286c76..778d4c63a985 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1092,14 +1092,28 @@ static void ublk_align_max_io_size(struct ublk_device *ub) round_down(max_rq_bytes, PAGE_SIZE) >> ub->bs_shift; } -/* add tag_set & cdev, cleanup everything in case of failure */ -static int ublk_add_dev(struct ublk_device *ub) +static void ublk_negotiate_features(struct ublk_device *ub) { - int err = -ENOMEM; + unsigned long *map = (unsigned long *)&ub->dev_info.flags[0]; /* We are not ready to support zero copy */ ub->dev_info.flags[0] &= ~UBLK_F_SUPPORT_ZERO_COPY; + /* + * 128bit flags will be copied back to userspace as feature + * negotiation result, so have to clear flags which driver + * doesn't support yet, then userspace can get correct flags + * (features) to handle. + */ + bitmap_clear(map, __UBLK_F_NR_BITS, 128 - __UBLK_F_NR_BITS); +} + +/* add tag_set & cdev, cleanup everything in case of failure */ +static int ublk_add_dev(struct ublk_device *ub) +{ + int err = -ENOMEM; + + ublk_negotiate_features(ub); ub->bs_shift = ilog2(ub->dev_info.block_size); ub->dev_info.nr_hw_queues = min_t(unsigned int, ub->dev_info.nr_hw_queues, nr_cpu_ids); @@ -1491,6 +1505,8 @@ static int __init ublk_init(void) { int ret; + BUILD_BUG_ON(__UBLK_F_NR_BITS > 128); + init_waitqueue_head(&ublk_idr_wq); ret = misc_register(&ublk_misc); diff --git a/include/uapi/linux/ublk_cmd.h b/include/uapi/linux/ublk_cmd.h index 917580b34198..49e4950a9181 100644 --- a/include/uapi/linux/ublk_cmd.h +++ b/include/uapi/linux/ublk_cmd.h @@ -42,17 +42,24 @@ /* tag bit is 12bit, so at most 4096 IOs for each queue */ #define UBLK_MAX_QUEUE_DEPTH 4096 + +enum ublk_flag_bits { + __UBLK_F_SUPPORT_ZERO_COPY, + __UBLK_F_URING_CMD_COMP_IN_TASK, + __UBLK_F_NR_BITS, +}; + /* * zero copy requires 4k block size, and can remap ublk driver's io * request into ublksrv's vm space */ -#define UBLK_F_SUPPORT_ZERO_COPY (1UL << 0) +#define UBLK_F_SUPPORT_ZERO_COPY (1ULL << __UBLK_F_SUPPORT_ZERO_COPY) /* * Force to complete io cmd via io_uring_cmd_complete_in_task so that * performance comparison is done easily with using task_work_add */ -#define UBLK_F_URING_CMD_COMP_IN_TASK (1UL << 1) +#define UBLK_F_URING_CMD_COMP_IN_TASK (1ULL << __UBLK_F_URING_CMD_COMP_IN_TASK) /* device state */ #define UBLK_S_DEV_DEAD 0 -- 2.31.1