xref: /aosp_15_r20/external/ublksrv/include/ublksrv.h (revision 94c4a1e103eb1715230460aab379dff275992c20)
1 // SPDX-License-Identifier: MIT or LGPL-2.1-only
2 
3 /**
4  * @file ublksrv.h
5  *
6  * libublksrv APIs
7  *
8  * This header define the interfaces of libublksrv
9  */
10 
11 #ifndef UBLKSRV_INC_H
12 #define UBLKSRV_INC_H
13 
14 #include <stdbool.h>
15 #include <assert.h>
16 
17 #include "liburing.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #include "ublk_cmd.h"
24 
25 #define	MAX_NR_HW_QUEUES 32
26 #define	MAX_QD		UBLK_MAX_QUEUE_DEPTH
27 #define	MAX_BUF_SIZE    (32U << 20)
28 
29 #define	DEF_NR_HW_QUEUES 1
30 #define	DEF_QD		128
31 #define	DEF_BUF_SIZE	(512 << 10)
32 
33 /************ stored in ublksrv_ctrl_dev_info->ublksrv_flags *******/
34 /*
35  * target may not use io_uring for handling io, so eventfd is required
36  * for wakeup io command io_uring context
37  */
38 #define UBLKSRV_F_NEED_EVENTFD		(1UL << 1)
39 
40 struct io_uring;
41 struct io_uring_cqe;
42 struct ublksrv_aio_ctx;
43 struct ublksrv_ctrl_dev;
44 
45 /**
46  * Generic data for creating one ublk control device, which is used for
47  * sending control commands to /dev/ublk-control.
48  *
49  * Control commands(UBLK_CMD_*) are defined in ublk_cmd.h.
50  */
51 struct ublksrv_dev_data {
52 	int		dev_id;
53 	unsigned	max_io_buf_bytes;
54 	unsigned short	nr_hw_queues;
55 	unsigned short	queue_depth;
56 	const char	*tgt_type;
57 	const struct ublksrv_tgt_type *tgt_ops;
58 	int		tgt_argc;
59 	char		**tgt_argv;
60 	const char	*run_dir;
61 	unsigned long	flags;
62 	unsigned long	ublksrv_flags;
63 	unsigned long   reserved[7];
64 };
65 
66 /**
67  * IO data passed to target io handling callbacks, such as
68  * ->handle_io_async() and ->tgt_io_done().
69  */
70 struct ublk_io_data {
71 	/** tag of this io data, unique in queue wide */
72 	int tag;
73 	unsigned int pad;
74 
75 	/** io description from ublk driver */
76 	const struct ublksrv_io_desc *iod;
77 
78 	/**
79 	 * IO private data, created in ublksrv_queue_init(),
80 	 * data size is specified in ublksrv_tgt_info.io_data_size
81 	 */
82 	void *private_data;
83 };
84 
85 /* queue state is only retrieved via ublksrv_queue_state() API */
86 #define UBLKSRV_QUEUE_STOPPING	(1U << 0)
87 #define UBLKSRV_QUEUE_IDLE	(1U << 1)
88 #define UBLKSRV_QUEUE_IOCTL_OP	(1U << 2)
89 #define UBLKSRV_USER_COPY	(1U << 3)
90 
91 /**
92  * ublksrv_queue is 1:1 mapping with ublk driver's blk-mq queue, and
93  * has same queue depth with ublk driver's blk-mq queue.
94  */
95 struct ublksrv_queue {
96 	/** queue id */
97 	int q_id;
98 
99 	/** So far, all queues in same device has same depth */
100 	int q_depth;
101 
102 	/** io uring for handling io commands() from ublk driver */
103 	struct io_uring *ring_ptr;
104 
105 	/** which device this queue belongs to */
106 	const struct ublksrv_dev *dev;
107 
108 	/** queue's private data, passed from ublksrv_queue_init() */
109 	void *private_data;
110 };
111 
112 struct ublksrv_tgt_type;
113 
114 #define  UBLKSRV_TGT_MAX_FDS	32
115 
116 /**
117  *
118  * ublksrv_tgt_info: target data
119  *
120  */
121 struct ublksrv_tgt_info {
122 	/** device size */
123 	unsigned long long dev_size;
124 
125 	/**
126 	 * target ring depth, for handling target IOs
127 	 */
128 	unsigned int tgt_ring_depth;
129 
130 	/** how many FDs regisgered */
131 	unsigned int nr_fds;
132 
133 	/** file descriptor table */
134 	int fds[UBLKSRV_TGT_MAX_FDS];
135 
136 	/** target private data */
137 	void *tgt_data;
138 
139 	/**
140 	 * Extra IO slots for each queue, target code can reserve some
141 	 * slots for handling internal IO, such as meta data IO, then
142 	 * ublk_io instances can be assigned for these extra IOs.
143 	 *
144 	 * IO slot is useful for storing coroutine data which is for
145 	 * handling this (meta) IO.
146 	 */
147 	unsigned int extra_ios;
148 
149 	/** size of io private data */
150 	unsigned int io_data_size;
151 
152 	/**
153 	 * target io handling type, target main job is to implement
154 	 * callbacks defined in this type
155 	 */
156 	const struct ublksrv_tgt_type *ops;
157 
158 	/**
159 	 * If target needs to override default max workers for io_uring,
160 	 * initialize io_wq_max_workers with proper value, otherwise
161 	 * keep them as zero
162 	 */
163 	unsigned int iowq_max_workers[2];
164 
165 	unsigned long reserved[4];
166 };
167 
168 /**
169  * ublksrv device
170  */
171 struct ublksrv_dev {
172 	/** device data */
173 	struct ublksrv_tgt_info tgt;
174 };
175 
176 /**
177  *
178  * ublksrv_tgt_type: target type
179  *
180  */
181 struct ublksrv_tgt_type {
182 	/**
183 	 * One IO request comes from /dev/ublkbN, so notify target code
184 	 * for handling the IO. Inside target code, the IO can be handled
185 	 * with our io_uring too, if this is true, ->tgt_io_done callback
186 	 * has to be implemented. Otherwise, target can implement
187 	 * ->handle_event() for processing io completion there.
188 	 *
189 	 *  Required.
190 	 */
191 	int (*handle_io_async)(const struct ublksrv_queue *,
192 			const struct ublk_io_data *io);
193 
194 	/**
195 	 * target io is handled by our io_uring, and once the target io
196 	 * is completed, this callback is called.
197 	 *
198 	 * Optional, only required iff this target io is handled by ublksrv's
199 	 * io_uring.
200 	 */
201 	void (*tgt_io_done)(const struct ublksrv_queue *,
202 			const struct ublk_io_data *io,
203 			const struct io_uring_cqe *);
204 
205 	/**
206 	 * Someone has written to our eventfd, so let target handle the
207 	 * event, most of times, it is for handling io completion by
208 	 * calling ublksrv_complete_io() which has to be run in ubq_daemon
209 	 * context.
210 	 *
211 	 * Follows the typical scenario:
212 	 *
213 	 * 1) one target io is completed in target pthread context, so
214 	 * target code calls ublksrv_queue_send_event for notifying ubq
215 	 * daemon
216 	 *
217 	 * 2) ubq daemon gets notified, so wakeup from io_uring_enter(),
218 	 * then found eventfd is completed, so call ->handle_event()
219 	 *
220 	 * 3) inside ->handle_event(), if any io represented by one io
221 	 * command is completed, ublksrv_complete_io() is called for
222 	 * this io.
223 	 *
224 	 * 4) after returning from ->handle_event(), ubq_daemon will
225 	 * queue & submit the eventfd io immediately for getting
226 	 * notification from future event.
227 	 *
228 	 * Optional. Only needed if target IO is handled by target its
229 	 * own pthread context.
230 	 */
231 	void (*handle_event)(const struct ublksrv_queue *);
232 
233 	/**
234 	 * One typical use case is to flush meta data, which is usually done
235 	 * in background. So there isn't any tag from libublksrv for this kind
236 	 * of IOs, and the target code has to request for allocating extra ios
237 	 * by passing tgt_type->extra_ios and let this callback consume & handle
238 	 * these extra IOs.
239 	 *
240 	 * nr_queued_io: count of queued IOs in ublksrv_reap_events_uring of
241 	 * this time
242 	 *
243 	 * Optional.
244 	 */
245 	void (*handle_io_background)(const struct ublksrv_queue *, int
246 			nr_queued_io);
247 
248 	/**
249 	 * show target specific command line for adding new device
250 	 *
251 	 * Be careful: this callback is the only one which is not run from
252 	 * ublk device daemon task context.
253 	 */
254 	void (*usage_for_add)(void);
255 
256 	/**
257 	 * initialize this new target, argc/argv includes target specific
258 	 * command line parameters
259 	 *
260 	 * Required.
261 	 */
262 	int (*init_tgt)(struct ublksrv_dev *, int type, int argc,
263 			char *argv[]);
264 
265 	/**
266 	 * Deinitialize this target
267 	 *
268 	 * Optional.
269 	 */
270 	void (*deinit_tgt)(const struct ublksrv_dev *);
271 
272 	/**
273 	 * callback for allocating io buffer
274 	 *
275 	 * Optional.
276 	 */
277 	void *(*alloc_io_buf)(const struct ublksrv_queue *q, int tag, int size);
278 	/**
279 	 * callback for freeing io buffer
280 	 *
281 	 * Optional.
282 	 */
283 	void (*free_io_buf)(const struct ublksrv_queue *q, void *buf, int tag);
284 
285 	/**
286 	 * Called when the ublksrv io_uring is idle.
287 	 *
288 	 * Optional.
289 	 */
290 	void (*idle_fn)(const struct ublksrv_queue *q, bool enter);
291 
292 	/** target type */
293 	int  type;
294 
295 	/** flags required for ublk driver */
296 	unsigned ublk_flags;
297 
298 	/** flags required for ublksrv */
299 	unsigned ublksrv_flags;
300 	unsigned pad;
301 
302 	/** target name */
303 	const char *name;
304 
305 	/**
306 	 * recovery callback for this target
307 	 *
308 	 * Required.
309 	 */
310 	int (*recovery_tgt)(struct ublksrv_dev *, int type);
311 
312 	/**
313 	 * queue_data_ptr points to address of q->priviate_data, so that
314 	 * we still can pass 'const struct ublksrv_queue *', meantime
315 	 * queue data can be stored to q->private_data via queue_data_ptr.
316 	 *
317 	 * ->init_queue provides one chance to override/init the passed
318 	 * "queue_data" to ublksrv_queue_init(), "queue_data" is set to
319 	 * q->private_data before calling ->init_queue()
320 	 */
321 	int (*init_queue)(const struct ublksrv_queue *, void **queue_data_ptr);
322 
323 	/** deinit queue data, counter pair of ->init_queue */
324 	void (*deinit_queue)(const struct ublksrv_queue *);
325 
326 	unsigned long reserved[5];
327 };
328 
329 /**
330  * Build sqe->user_data.
331  *
332  * io_uring relies on ->user_data to map cqe to the submitted io represented by
333  * sqe, encodes ublk interested info into ->user_data for handling IO
334  * completion efficiently.
335  *
336  * @param tag ublk io tag
337  * @param op operation code of submitted io
338  * @param tgt_data target data for this io
339  * @param is_taget_io is this one target io, and it should be true for target,
340  * 	and false for ublksrv built uring command, which is for communicating
341  * 	with ublk_drv
342  */
build_user_data(unsigned tag,unsigned op,unsigned tgt_data,unsigned is_target_io)343 static inline __u64 build_user_data(unsigned tag, unsigned op,
344 		unsigned tgt_data, unsigned is_target_io)
345 {
346 	assert(!(tag >> 16) && !(op >> 8) && !(tgt_data >> 16));
347 
348 	return tag | (op << 16) | (tgt_data << 24) | (__u64)is_target_io << 63;
349 }
350 
user_data_to_tag(__u64 user_data)351 static inline unsigned int user_data_to_tag(__u64 user_data)
352 {
353 	return user_data & 0xffff;
354 }
355 
user_data_to_op(__u64 user_data)356 static inline unsigned int user_data_to_op(__u64 user_data)
357 {
358 	return (user_data >> 16) & 0xff;
359 }
360 
user_data_to_tgt_data(__u64 user_data)361 static inline unsigned int user_data_to_tgt_data(__u64 user_data)
362 {
363 	return (user_data >> 24) & 0xffff;
364 }
365 
ublk_pos(__u16 q_id,__u16 tag,__u32 offset)366 static inline __u64 ublk_pos(__u16 q_id, __u16 tag, __u32 offset)
367 {
368 	assert(!(offset & ~UBLK_IO_BUF_BITS_MASK));
369 
370 	return UBLKSRV_IO_BUF_OFFSET +
371 		((((__u64)q_id) << UBLK_QID_OFF) |
372 		(((__u64)tag) << UBLK_TAG_OFF) | (__u64)offset);
373 }
374 
375 /**
376  * \defgroup ctrl_dev control device API
377  *
378  *  Most of APIs are for sending command to ublk control device(/dev/ublk-control),
379  *  and some of them are just for device management purpose, such as, retrieving
380  *  device json buffer, run_dir, prepare for recovering, get cached device info ...
381  *
382  *  Almost all these APIs can be called in random context by random io uring
383  *  context
384  *
385  *  @{
386  */
387 
388 /**
389  * Deinit one control device
390  *
391  * @param dev the ublksrv control device instance
392  *
393  */
394 extern void ublksrv_ctrl_deinit(struct ublksrv_ctrl_dev *dev);
395 
396 /**
397  * Allocate and init one control device
398  *
399  * @param data data for allocating & initializing this control device
400  *
401  */
402 extern struct ublksrv_ctrl_dev *ublksrv_ctrl_init(struct ublksrv_dev_data *data);
403 
404 /**
405  * Retrieve and store each queue's cpu affinity info into private data of the
406  * control device by sending commands to ublk control device
407  *
408  * @param ctrl_dev the ublksrv control device instance
409  *
410  */
411 extern int ublksrv_ctrl_get_affinity(struct ublksrv_ctrl_dev *ctrl_dev);
412 
413 /**
414  * Add one ublk device by sending command to ublk driver
415  *
416  * @param dev the ublksrv control device instance
417  */
418 extern int ublksrv_ctrl_add_dev(struct ublksrv_ctrl_dev *dev);
419 
420 /**
421  * Delete this ublk device by sending command to ublk driver
422  *
423  * @param dev the ublksrv control device instance
424  */
425 extern int ublksrv_ctrl_del_dev(struct ublksrv_ctrl_dev *dev);
426 
427 /**
428  * Delete this ublk device asynchronously by sending command to ublk driver
429  *
430  * @param dev the ublksrv control device instance
431  */
432 extern int ublksrv_ctrl_del_dev_async(struct ublksrv_ctrl_dev *dev);
433 
434 /**
435  * Retrieve ublk device info by sending command to ublk control device
436  *
437  * @param dev the ublksrv control device instance
438  */
439 extern int ublksrv_ctrl_get_info(struct ublksrv_ctrl_dev *dev);
440 
441 /**
442  * Stop the specified ublk device by sending command to ublk control device
443  *
444  * @param dev the ublksrv control device instance
445  */
446 extern int ublksrv_ctrl_stop_dev(struct ublksrv_ctrl_dev *dev);
447 
448 /**
449  * Dump this ublk device
450  *
451  * @param dev the ublksrv control device instance
452  * @param buf ublk device json buffer, optional
453  */
454 extern void ublksrv_ctrl_dump(struct ublksrv_ctrl_dev *dev, const char *buf);
455 
456 /**
457  * Start this ublk device by sending command to ublk control device
458  *
459  * @param ctrl_dev the ublksrv control device instance
460  * @param daemon_pid pid of the ublksrv process
461  */
462 extern int ublksrv_ctrl_start_dev(struct ublksrv_ctrl_dev *ctrl_dev,
463 		int daemon_pid);
464 
465 /**
466  * Set specified device parameter by sending command to ublk control device
467  *
468  * @param dev the ublksrv control device instance
469  * @param params the specified parameter for setting device
470  */
471 extern int ublksrv_ctrl_set_params(struct ublksrv_ctrl_dev *dev,
472 		struct ublk_params *params);
473 
474 /**
475  * Get specified device parameter by sending command to ublk control device
476  *
477  * @param dev the ublksrv control device instance
478  * @param params the parameter buffer for storing the device parameter
479  */
480 extern int ublksrv_ctrl_get_params(struct ublksrv_ctrl_dev *dev,
481 		struct ublk_params *params);
482 
483 /**
484  * Start to recovery device by sending command to ublk control device
485  *
486  * @param dev the ublksrv control device instance
487  */
488 extern int ublksrv_ctrl_start_recovery(struct ublksrv_ctrl_dev *dev);
489 
490 /**
491  * End recovery device by sending command to ublk control device
492  *
493  * Once this command is successful, the device is recovered to normal state
494  *
495  * @param dev the ublksrv control device instance
496  * @param daemon_pid pid of the new ublksrv process
497  */
498 extern int ublksrv_ctrl_end_recovery(struct ublksrv_ctrl_dev *dev,
499 		int daemon_pid);
500 
501 /**
502  * Return cached device info for this device
503  *
504  * @param dev the ublksrv control device instance
505  */
506 extern const struct ublksrv_ctrl_dev_info *ublksrv_ctrl_get_dev_info(
507 		const struct ublksrv_ctrl_dev *dev);
508 
509 /**
510  * Return feature set supported by ublk driver
511  *
512  * @features points to buffer for holding the returned features
513  */
514 extern int ublksrv_ctrl_get_features(struct ublksrv_ctrl_dev *dev,
515 		__u64 *features);
516 
517 /**
518  * Return run dir of ublk device
519  *
520  * Device pid file and json string stored under this dir
521  *
522  * @param dev the ublksrv control device instance
523  */
524 extern const char *ublksrv_ctrl_get_run_dir(const struct ublksrv_ctrl_dev *dev);
525 
526 /**
527  * Prepare for starting to recovery device
528  *
529  * Setup target type, run_dir and json buffer before starting to recovery device.
530  *
531  * @param dev the ublksrv control device instance
532  * @param tgt_type target type name of this device
533  * @param tgt_ops target type of this devie
534  * @param recovery_jbuf points to device json buffer
535  */
536 extern void ublksrv_ctrl_prep_recovery(struct ublksrv_ctrl_dev *dev,
537 		const char *tgt_type, const struct ublksrv_tgt_type *tgt_ops,
538 		const char *recovery_jbuf);
539 
540 /**
541  * Return device's json buffer
542  *
543  * Setup target type, run_dir and json buffer before starting to recovery device.
544  *
545  * @param dev the ublksrv control device instance
546  */
547 extern const char *ublksrv_ctrl_get_recovery_jbuf(const struct ublksrv_ctrl_dev *dev);
548 
549 /**
550  * Return true if this control device is for recovering
551  *
552  * @param dev the ublksrv control device instance
553  */
554 extern bool ublksrv_is_recovering(const struct ublksrv_ctrl_dev *ctrl_dev);
555 
556 /** @} */ // end of ctrl_dev group
557 
558 
559 /**
560  * \defgroup ublksrv_dev ublksrv device API
561  *
562  * ublksrv device ("/dev/ublkcN") level APIs, and ublksrv device focuses on
563  * IO handling related function
564  *
565  * All APIs in this group should be called in ublksrv daemon process context
566  *
567  *  @{
568  */
569 
570 /**
571  * Allocate and initialize ublksrv device
572  *
573  * @param ctrl_dev the ublksrv control device instance
574  */
575 extern const struct ublksrv_dev *ublksrv_dev_init(const struct ublksrv_ctrl_dev *
576 		ctrl_dev);
577 
578 /**
579  * Deinitialize and free ublksrv device
580  *
581  * @param dev the ublksrv device instance
582  */
583 extern void ublksrv_dev_deinit(const struct ublksrv_dev *dev);
584 
585 /**
586  * Return the associated ublksrv control device instance
587  *
588  * @param dev the ublksrv device instance
589  */
590 extern const struct ublksrv_ctrl_dev *ublksrv_get_ctrl_dev(
591 		const struct ublksrv_dev *dev);
592 
593 /**
594  * Return pid file FD of this ublksrv device
595  *
596  * @param dev the ublksrv device instance
597  */
598 extern int ublksrv_get_pidfile_fd(const struct ublksrv_dev *dev);
599 
600 /**
601  * Set completion queue depth of this ublksrv device
602  *
603  * @param dev the ublksrv device instance
604  * @param cq_depth depth of the completion queue of io_uring
605  */
606 extern void ublksrv_dev_set_cq_depth(struct ublksrv_dev *dev, int cq_depth);
607 
608 /**
609  * Get completion queue depth of this ublksrv device
610  *
611  * @param dev the ublksrv device instance
612  */
613 extern int ublksrv_dev_get_cq_depth(struct ublksrv_dev *dev);
614 
615 /**
616  *
617  * Apply OOM porotection
618  */
619 extern void ublksrv_apply_oom_protection(void);
620 
621 /** @} */ // end of ublksrv_dev group
622 
623 /* target json has to include the following key/value */
624 #define UBLKSRV_TGT_NAME_MAX_LEN 32
625 struct ublksrv_tgt_base_json {
626 	char name[UBLKSRV_TGT_NAME_MAX_LEN];
627 	int type;
628 	unsigned int pad;
629 	unsigned long long dev_size;
630 	unsigned long reserved[8];
631 };
632 
633 /**
634  * \defgroup ublksrv_json ublksrv json string API
635  *
636  * ublksrv json string APIs
637  *
638  * APIs for serializing/deserializing device data to/from json string
639  *
640  *  @{
641  */
642 
643 /**
644  * Serialize json buffer from device's ublksrv_ctrl_dev_info data
645  *
646  * @param dev the ublksrv control device instance
647  * @param buf json buffer
648  * @param len length of json buffer
649  */
650 extern int ublksrv_json_write_dev_info(const struct ublksrv_ctrl_dev *dev,
651 		char *buf, int len);
652 
653 /**
654  * Deserialize json buffer to ublksrv_ctrl_dev_info instance
655  *
656  * @param json_buf json buffer
657  * @param info device info for storing the parsed ublksrv_ctrl_dev_info
658  */
659 extern int ublksrv_json_read_dev_info(const char *json_buf,
660 		struct ublksrv_ctrl_dev_info *info);
661 
662 /**
663  * Serialize json buffer from ublksrv queue
664  *
665  * @param dev the ublksrv control device instance
666  * @param jbuf json buffer
667  * @param len length of json buffer
668  * @param qid queue id
669  * @param ubq_daemon_tid queue pthread tid
670  */
671 extern int ublksrv_json_write_queue_info(const struct ublksrv_ctrl_dev *dev,
672 		char *jbuf, int len, int qid, int ubq_daemon_tid);
673 
674 /**
675  * Deserialize json buffer to ublksrv queue
676  *
677  * @param jbuf json buffer
678  * @param qid queue id
679  * @param tid queue pthread tid
680  * @param affinity_buf queue affinity buffer
681  * @param len length of json buffer
682  */
683 extern int ublksrv_json_read_queue_info(const char *jbuf, int qid,
684 		unsigned *tid, char *affinity_buf, int len);
685 
686 /**
687  * Deserialize json buffer to target data
688  *
689  * @param jbuf json buffer
690  * @param tgt_buf target buffer
691  * @param len length of json buffer
692  */
693 extern int ublksrv_json_read_target_info(const char *jbuf, char *tgt_buf,
694 		int len);
695 
696 /**
697  * Deserialize json buffer to target string field
698  *
699  * @param jbuf json buffer
700  * @param len length of json buffer
701  * @param name string name
702  * @param val string value
703  */
704 extern int ublksrv_json_read_target_str_info(const char *jbuf, int len,
705 		const char *name, char *val);
706 
707 /**
708  * Deserialize json buffer to target ulong field
709  *
710  * @param jbuf json buffer
711  * @param name field name with ulong type
712  * @param val field value with ulong type
713  */
714 extern int ublksrv_json_read_target_ulong_info(const char *jbuf,
715 		const char *name, long *val);
716 
717 /**
718  * Serialize json buffer from target field with string type
719  *
720  * @param jbuf json buffer
721  * @param len length of json buffer
722  * @param name field name with string type
723  * @param val field value with string type
724  */
725 extern int ublksrv_json_write_target_str_info(char *jbuf, int len,
726 		const char *name, const char *val);
727 
728 extern int ublksrv_json_write_target_long_info(char *jbuf, int len,
729 		const char *name, long val);
730 
731 /**
732  * Serialize json buffer from target field with ulong type
733  *
734  * @param jbuf json buffer
735  * @param len length of json buffer
736  * @param name field name with ulong type
737  * @param val field value with ulong type
738  */
739 extern int ublksrv_json_write_target_ulong_info(char *jbuf, int len,
740 		const char *name, unsigned long val);
741 
742 extern void ublksrv_json_dump(const char *jbuf);
743 
744 /**
745  * Deserialize json buffer to ublksrv_tgt_base_json instance
746  *
747  * @param jbuf json buffer
748  * @param tgt ublksrv_tgt_base_json instance
749  */
750 extern int ublksrv_json_read_target_base_info(const char *jbuf,
751 		struct ublksrv_tgt_base_json *tgt);
752 
753 /**
754  * Serialize json buffer from ublksrv_tgt_base_json
755  *
756  * @param jbuf json buffer
757  * @param len length of json buffer
758  * @param tgt ublksrv_tgt_base_json instance
759  */
760 extern int ublksrv_json_write_target_base_info(char *jbuf, int len,
761 		const struct ublksrv_tgt_base_json *tgt);
762 
763 /**
764  * Deserialize json buffer to ublk_params instance
765  *
766  * @param p ublk_params instance
767  * @param jbuf json buffer
768  */
769 extern int ublksrv_json_read_params(struct ublk_params *p,
770 		const char *jbuf);
771 
772 /**
773  * Serialize json buffer from ublk_params instance
774  *
775  * @param p ublk_params instance
776  * @param jbuf json buffer
777  * @param len length of json buffer
778  */
779 extern int ublksrv_json_write_params(const struct ublk_params *p,
780 		char *jbuf, int len);
781 extern int ublksrv_json_dump_params(const char *jbuf);
782 
783 /**
784  * Return actual length of the json buffer
785  *
786  * @param jbuf json buffer
787  */
788 extern int ublksrv_json_get_length(const char *jbuf);
789 
790 /** @} */ // end of ublksrv_json group
791 
792 /**
793  * \defgroup ublksrv_queue ublksrv queue API
794  *
795  * ublksrv queue level APIs
796  *
797  * All APIs in this group is supposed to be called in the queue context
798  *
799  *  @{
800  */
801 
802 /**
803  * Return the specified io private data
804  *
805  * Each IO has unique tag, so we use tag to represent specified io.
806  *
807  * Inside ->init_tgt() callback, target code sets io private data
808  * size via dev->tgt.io_data_size, then io private data will be allocated
809  * in ublksrv_queue_init(). The allocated io private data is very useful
810  * to store target specific io data, then runtime memory allocation in io
811  * handling code path can be avoided.
812  *
813  * @param q the ublksrv queue instance
814  * @param tag tag for this io
815  */
816 extern void *ublksrv_io_private_data(const struct ublksrv_queue *q, int tag);
817 
818 /**
819  * Return the specified io generic io data
820  *
821  * Each IO has unique tag, so we use tag to represent specified io.
822  *
823  * @param q the ublksrv queue instance
824  * @param tag tag for this io
825  * @return 'struct ublk_io_data' instance, which is for storing io descriptor,
826  * 	tag, and private data
827  */
828 extern const struct ublk_io_data *ublksrv_queue_get_io_data(
829 		const struct ublksrv_queue *q, int tag);
830 
831 /**
832  * Return pre-allocated io buffer
833  *
834  * Each IO has unique tag, so we use tag to represent specified io.
835  *
836  * @param q the ublksrv queue instance
837  * @param tag tag for this io
838  * @return pre-allocated io buffer for this io
839  */
840 extern void *ublksrv_queue_get_io_buf(const struct ublksrv_queue *q, int tag);
841 
842 /**
843  * Return current queue state
844  *
845  * queue state is usually for debug purpose
846  *
847  * @param q the ublksrv queue instance
848  * @return queue current state
849  */
850 extern unsigned int ublksrv_queue_state(const struct ublksrv_queue *q);
851 
852 /**
853  * Allocate and initialize ublksrv queue instance
854  *
855  * @param dev the ublksrv device instance
856  * @param q_id queue id
857  * @param queue_data queue private data
858  */
859 extern const struct ublksrv_queue *ublksrv_queue_init(const struct ublksrv_dev *dev,
860 		unsigned short q_id, void *queue_data);
861 
862 /**
863  * Deinit & free ublksrv queue instance
864  *
865  * @param q the ublksrv queue instance
866  */
867 extern void ublksrv_queue_deinit(const struct ublksrv_queue *q);
868 
869 /**
870  * Return how many unconsumed cqes in CQ of queue uring
871  *
872  * @param q the ublksrv queue instance
873  *
874  * Return -1 if uring isn't setup correctly
875  */
876 extern int ublksrv_queue_unconsumed_cqes(const struct ublksrv_queue *q);
877 
878 extern int ublksrv_queue_handled_event(const struct ublksrv_queue *q);
879 extern int ublksrv_queue_send_event(const struct ublksrv_queue *q);
880 
881 /**
882  * Return the specified queue instance by ublksrv device and qid
883  *
884  * Retrieve queue instance by ublksrv device and queue id
885  *
886  * @param dev the ublksrv device instance
887  * @param q_id queue id
888  */
889 extern const struct ublksrv_queue *ublksrv_get_queue(const struct ublksrv_dev *dev,
890 		int q_id);
891 
892 /**
893  * Process target IO & IO command from this queue's io_uring
894  *
895  * Handle incoming io command by calling target ->handle_io_async(), or
896  * call ->tgt_io_done() if target IO is completed.
897  *
898  * It is the engine of libulksrv, almost everything is driven by this
899  * API.
900  *
901  * @param q the ublksrv queue instance
902  */
903 extern int ublksrv_process_io(const struct ublksrv_queue *q);
904 
905 /**
906  * Complete specified io with result of 'res'
907  *
908  * This API will tell ublk driver via /dev/ublkcN that this IO is completed.
909  *
910  * @param q the ublksrv queue instance
911  * @param tag the io to be completed
912  * @param res io result
913  */
914 extern int ublksrv_complete_io(const struct ublksrv_queue *q, unsigned tag, int res);
915 /** @} */ // end of ublksrv_queue group
916 
917 #ifdef __cplusplus
918 }
919 #endif
920 #endif
921