Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: ublk: prepare for supporting stripe target

- pass 'truct dev_ctx *ctx' to target init function

- add 'private_data' to 'struct ublk_dev' for storing target specific data

- add 'private_data' to 'struct ublk_io' for storing per-IO data

- add 'tgt_ios' to 'struct ublk_io' for counting how many io_uring ios
for handling the current io command

- add helper ublk_get_io() for supporting stripe target

- add two helpers for simplifying target io handling

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250322093218.431419-6-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Ming Lei and committed by
Jens Axboe
8842b72a 10d962da

+38 -6
+1 -1
tools/testing/selftests/ublk/file_backed.c
··· 123 123 q->io_inflight--; 124 124 } 125 125 126 - static int ublk_loop_tgt_init(struct ublk_dev *dev) 126 + static int ublk_loop_tgt_init(const struct dev_ctx *ctx, struct ublk_dev *dev) 127 127 { 128 128 unsigned long long bytes; 129 129 int ret;
+3 -3
tools/testing/selftests/ublk/kublk.c
··· 381 381 382 382 #define WAIT_USEC 100000 383 383 #define MAX_WAIT_USEC (3 * 1000000) 384 - static int ublk_dev_prep(struct ublk_dev *dev) 384 + static int ublk_dev_prep(const struct dev_ctx *ctx, struct ublk_dev *dev) 385 385 { 386 386 int dev_id = dev->dev_info.dev_id; 387 387 unsigned int wait_usec = 0; ··· 404 404 405 405 dev->fds[0] = fd; 406 406 if (dev->tgt.ops->init_tgt) 407 - ret = dev->tgt.ops->init_tgt(dev); 407 + ret = dev->tgt.ops->init_tgt(ctx, dev); 408 408 if (ret) 409 409 close(dev->fds[0]); 410 410 return ret; ··· 666 666 667 667 ublk_dbg(UBLK_DBG_DEV, "%s enter\n", __func__); 668 668 669 - ret = ublk_dev_prep(dev); 669 + ret = ublk_dev_prep(ctx, dev); 670 670 if (ret) 671 671 return ret; 672 672
+33 -1
tools/testing/selftests/ublk/kublk.h
··· 94 94 unsigned short refs; /* used by target code only */ 95 95 96 96 int result; 97 + 98 + unsigned short tgt_ios; 99 + void *private_data; 97 100 }; 98 101 99 102 struct ublk_tgt_ops { 100 103 const char *name; 101 - int (*init_tgt)(struct ublk_dev *); 104 + int (*init_tgt)(const struct dev_ctx *ctx, struct ublk_dev *); 102 105 void (*deinit_tgt)(struct ublk_dev *); 103 106 104 107 int (*queue_io)(struct ublk_queue *, int tag); ··· 149 146 int nr_fds; 150 147 int ctrl_fd; 151 148 struct io_uring ring; 149 + 150 + void *private_data; 152 151 }; 153 152 154 153 #ifndef offsetof ··· 308 303 addr[1] = 0; 309 304 } 310 305 306 + static inline struct ublk_io *ublk_get_io(struct ublk_queue *q, unsigned tag) 307 + { 308 + return &q->ios[tag]; 309 + } 310 + 311 311 static inline int ublk_complete_io(struct ublk_queue *q, unsigned tag, int res) 312 312 { 313 313 struct ublk_io *io = &q->ios[tag]; ··· 320 310 ublk_mark_io_done(io, res); 321 311 322 312 return ublk_queue_io_cmd(q, io, tag); 313 + } 314 + 315 + static inline void ublk_queued_tgt_io(struct ublk_queue *q, unsigned tag, int queued) 316 + { 317 + if (queued < 0) 318 + ublk_complete_io(q, tag, queued); 319 + else { 320 + struct ublk_io *io = ublk_get_io(q, tag); 321 + 322 + q->io_inflight += queued; 323 + io->tgt_ios = queued; 324 + io->result = 0; 325 + } 326 + } 327 + 328 + static inline int ublk_completed_tgt_io(struct ublk_queue *q, unsigned tag) 329 + { 330 + struct ublk_io *io = ublk_get_io(q, tag); 331 + 332 + q->io_inflight--; 333 + 334 + return --io->tgt_ios == 0; 323 335 } 324 336 325 337 static inline int ublk_queue_use_zc(const struct ublk_queue *q)
+1 -1
tools/testing/selftests/ublk/null.c
··· 2 2 3 3 #include "kublk.h" 4 4 5 - static int ublk_null_tgt_init(struct ublk_dev *dev) 5 + static int ublk_null_tgt_init(const struct dev_ctx *ctx, struct ublk_dev *dev) 6 6 { 7 7 const struct ublksrv_ctrl_dev_info *info = &dev->dev_info; 8 8 unsigned long dev_size = 250UL << 30;