Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 : */
4 :
5 : #ifndef SPDK_FSDEV_MODULE_H
6 : #define SPDK_FSDEV_MODULE_H
7 :
8 : #include "spdk/stdinc.h"
9 : #include "spdk/fsdev.h"
10 : #include "spdk/queue.h"
11 : #include "spdk/tree.h"
12 : #include "spdk/thread.h"
13 : #include "spdk/util.h"
14 :
15 : #ifdef __cplusplus
16 : extern "C" {
17 : #endif
18 :
19 : /**
20 : * Filesystem device I/O
21 : *
22 : * This is an I/O that is passed to an spdk_fsdev.
23 : */
24 : struct spdk_fsdev_io;
25 :
26 : /** Filesystem device module */
27 : struct spdk_fsdev_module {
28 : /**
29 : * Initialization function for the module. Called by the fsdev library
30 : * during startup.
31 : *
32 : * Modules are required to define this function.
33 : */
34 : int (*module_init)(void);
35 :
36 : /**
37 : * Finish function for the module. Called by the fsdev library
38 : * after all fsdevs for all modules have been unregistered. This allows
39 : * the module to do any final cleanup before the fsdev library finishes operation.
40 : *
41 : * Modules are not required to define this function.
42 : */
43 : void (*module_fini)(void);
44 :
45 : /**
46 : * Function called to return a text string representing the module-level
47 : * JSON RPCs required to regenerate the current configuration. This will
48 : * include module-level configuration options, or methods to construct
49 : * fsdevs when one RPC may generate multiple fsdevs.
50 : *
51 : * Per-fsdev JSON RPCs (where one "construct" RPC always creates one fsdev)
52 : * may be implemented here, or by the fsdev's write_config_json function -
53 : * but not both. Fsdev module implementers may choose which mechanism to
54 : * use based on the module's design.
55 : *
56 : * \return 0 on success or Fsdev specific negative error code.
57 : */
58 : int (*config_json)(struct spdk_json_write_ctx *w);
59 :
60 : /** Name for the module being defined. */
61 : const char *name;
62 :
63 : /**
64 : * Returns the allocation size required for the backend for uses such as local
65 : * command structs, local SGL, iovecs, or other user context.
66 : */
67 : int (*get_ctx_size)(void);
68 :
69 : /**
70 : * Fields that are used by the internal fsdev subsystem. Fsdev modules
71 : * must not read or write to these fields.
72 : */
73 : struct __fsdev_module_internal_fields {
74 : TAILQ_ENTRY(spdk_fsdev_module) tailq;
75 : } internal;
76 : };
77 :
78 : typedef void (*spdk_fsdev_unregister_cb)(void *cb_arg, int rc);
79 :
80 : /**
81 : * Function table for a filesystem device backend.
82 : *
83 : * The backend filesystem device function table provides a set of APIs to allow
84 : * communication with a backend.
85 : */
86 : struct spdk_fsdev_fn_table {
87 : /** Destroy the backend filesystem device object */
88 : int (*destruct)(void *ctx);
89 :
90 : /** Process the I/O request. */
91 : void (*submit_request)(struct spdk_io_channel *ch, struct spdk_fsdev_io *);
92 :
93 : /** Get an I/O channel for the specific fsdev for the calling thread. */
94 : struct spdk_io_channel *(*get_io_channel)(void *ctx);
95 :
96 : /**
97 : * Negotiate fsdev device options.
98 : *
99 : * The function validates the desired options and adjust them to reflect it own capabilities.
100 : * The module can only reduce the requested cababilities.
101 : *
102 : * \return 0 on success or Fsdev specific negative error code.
103 : */
104 : int (*negotiate_opts)(void *ctx, struct spdk_fsdev_open_opts *opts);
105 :
106 : /**
107 : * Output fsdev-specific RPC configuration to a JSON stream. Optional - may be NULL.
108 : *
109 : * The JSON write context will be initialized with an open object, so the fsdev
110 : * driver should write all data necessary to recreate this fsdev by invoking
111 : * constructor method. No other data should be written.
112 : */
113 : void (*write_config_json)(struct spdk_fsdev *fsdev, struct spdk_json_write_ctx *w);
114 :
115 : /** Get memory domains used by fsdev. Optional - may be NULL.
116 : * Vfsdev module implementation should call \ref spdk_fsdev_get_memory_domains for underlying fsdev.
117 : * Vfsdev module must inspect types of memory domains returned by base fsdev and report only those
118 : * memory domains that it can work with. */
119 : int (*get_memory_domains)(void *ctx, struct spdk_memory_domain **domains, int array_size);
120 : };
121 :
122 : /**
123 : * Filesystem device IO completion callback.
124 : *
125 : * \param fsdev_io Filesystem device I/O that has completed.
126 : * \param cb_arg Callback argument specified when fsdev_io was submitted.
127 : */
128 : typedef void (*spdk_fsdev_io_completion_cb)(struct spdk_fsdev_io *fsdev_io, void *cb_arg);
129 :
130 : struct spdk_fsdev_name {
131 : char *name;
132 : struct spdk_fsdev *fsdev;
133 : RB_ENTRY(spdk_fsdev_name) node;
134 : };
135 :
136 : typedef TAILQ_HEAD(, spdk_fsdev_io) fsdev_io_tailq_t;
137 : typedef STAILQ_HEAD(, spdk_fsdev_io) fsdev_io_stailq_t;
138 :
139 : struct spdk_fsdev_file_handle;
140 : struct spdk_fsdev_file_object;
141 :
142 :
143 : /** The node ID of the root inode */
144 : #define SPDK_FUSE_ROOT_ID 1 /* Must be the same as FUSE_ROOT_ID in the fuse_kernel.h to avoid translation */
145 :
146 : struct spdk_fsdev {
147 : /** User context passed in by the backend */
148 : void *ctxt;
149 :
150 : /** Unique name for this filesystem device. */
151 : char *name;
152 :
153 : /**
154 : * Pointer to the fsdev module that registered this fsdev.
155 : */
156 : struct spdk_fsdev_module *module;
157 :
158 : /** function table for all ops */
159 : const struct spdk_fsdev_fn_table *fn_table;
160 :
161 : /** Negotiable device ops */
162 : struct spdk_fsdev_open_opts opts;
163 :
164 : /** Fields that are used internally by the fsdev subsystem. Fsdev modules
165 : * must not read or write to these fields.
166 : */
167 : struct __fsdev_internal_fields {
168 : /** Lock protecting fsdev */
169 : struct spdk_spinlock spinlock;
170 :
171 : /** The fsdev status */
172 : enum spdk_fsdev_status status;
173 :
174 : /** Callback function that will be called after fsdev destruct is completed. */
175 : spdk_fsdev_unregister_cb unregister_cb;
176 :
177 : /** Unregister call context */
178 : void *unregister_ctx;
179 :
180 : /** List of open descriptors for this filesystem device. */
181 : TAILQ_HEAD(, spdk_fsdev_desc) open_descs;
182 :
183 : TAILQ_ENTRY(spdk_fsdev) link;
184 :
185 : /** Fsdev name used for quick lookup */
186 : struct spdk_fsdev_name fsdev_name;
187 : } internal;
188 : };
189 :
190 : enum spdk_fsdev_io_type {
191 : SPDK_FSDEV_IO_LOOKUP,
192 : SPDK_FSDEV_IO_FORGET,
193 : SPDK_FSDEV_IO_GETATTR,
194 : SPDK_FSDEV_IO_SETATTR,
195 : SPDK_FSDEV_IO_READLINK,
196 : SPDK_FSDEV_IO_SYMLINK,
197 : SPDK_FSDEV_IO_MKNOD,
198 : SPDK_FSDEV_IO_MKDIR,
199 : SPDK_FSDEV_IO_UNLINK,
200 : SPDK_FSDEV_IO_RMDIR,
201 : SPDK_FSDEV_IO_RENAME,
202 : SPDK_FSDEV_IO_LINK,
203 : SPDK_FSDEV_IO_OPEN,
204 : SPDK_FSDEV_IO_READ,
205 : SPDK_FSDEV_IO_WRITE,
206 : SPDK_FSDEV_IO_STATFS,
207 : SPDK_FSDEV_IO_RELEASE,
208 : SPDK_FSDEV_IO_FSYNC,
209 : SPDK_FSDEV_IO_SETXATTR,
210 : SPDK_FSDEV_IO_GETXATTR,
211 : SPDK_FSDEV_IO_LISTXATTR,
212 : SPDK_FSDEV_IO_REMOVEXATTR,
213 : SPDK_FSDEV_IO_FLUSH,
214 : SPDK_FSDEV_IO_OPENDIR,
215 : SPDK_FSDEV_IO_READDIR,
216 : SPDK_FSDEV_IO_RELEASEDIR,
217 : SPDK_FSDEV_IO_FSYNCDIR,
218 : SPDK_FSDEV_IO_FLOCK,
219 : SPDK_FSDEV_IO_CREATE,
220 : SPDK_FSDEV_IO_ABORT,
221 : SPDK_FSDEV_IO_FALLOCATE,
222 : SPDK_FSDEV_IO_COPY_FILE_RANGE,
223 : __SPDK_FSDEV_IO_LAST
224 : };
225 :
226 : struct spdk_fsdev_io {
227 : /** The filesystem device that this I/O belongs to. */
228 : struct spdk_fsdev *fsdev;
229 :
230 : /** Enumerated value representing the I/O type. */
231 : uint8_t type;
232 :
233 : /** A single iovec element for use by this fsdev_io. */
234 : struct iovec iov;
235 :
236 : union {
237 : struct {
238 : struct spdk_fsdev_file_object *parent_fobject;
239 : char *name;
240 : } lookup;
241 : struct {
242 : struct spdk_fsdev_file_object *fobject;
243 : uint64_t nlookup;
244 : } forget;
245 : struct {
246 : struct spdk_fsdev_file_object *fobject;
247 : struct spdk_fsdev_file_handle *fhandle;
248 : } getattr;
249 : struct {
250 : struct spdk_fsdev_file_object *fobject;
251 : struct spdk_fsdev_file_handle *fhandle;
252 : struct spdk_fsdev_file_attr attr;
253 : uint32_t to_set;
254 : } setattr;
255 : struct {
256 : struct spdk_fsdev_file_object *fobject;
257 : } readlink;
258 : struct {
259 : struct spdk_fsdev_file_object *parent_fobject;
260 : char *target;
261 : char *linkpath;
262 : uid_t euid;
263 : gid_t egid;
264 : } symlink;
265 : struct {
266 : struct spdk_fsdev_file_object *parent_fobject;
267 : char *name;
268 : mode_t mode;
269 : dev_t rdev;
270 : uid_t euid;
271 : gid_t egid;
272 : } mknod;
273 : struct {
274 : struct spdk_fsdev_file_object *parent_fobject;
275 : char *name;
276 : mode_t mode;
277 : uid_t euid;
278 : gid_t egid;
279 : } mkdir;
280 : struct {
281 : struct spdk_fsdev_file_object *parent_fobject;
282 : char *name;
283 : } unlink;
284 : struct {
285 : struct spdk_fsdev_file_object *parent_fobject;
286 : char *name;
287 : } rmdir;
288 : struct {
289 : struct spdk_fsdev_file_object *parent_fobject;
290 : char *name;
291 : struct spdk_fsdev_file_object *new_parent_fobject;
292 : char *new_name;
293 : uint32_t flags;
294 : } rename;
295 : struct {
296 : struct spdk_fsdev_file_object *fobject;
297 : struct spdk_fsdev_file_object *new_parent_fobject;
298 : char *name;
299 : } link;
300 : struct {
301 : struct spdk_fsdev_file_object *fobject;
302 : uint32_t flags;
303 : } open;
304 : struct {
305 : struct spdk_fsdev_file_object *fobject;
306 : struct spdk_fsdev_file_handle *fhandle;
307 : size_t size;
308 : uint64_t offs;
309 : uint32_t flags;
310 : struct iovec *iov;
311 : uint32_t iovcnt;
312 : struct spdk_fsdev_io_opts *opts;
313 : } read;
314 : struct {
315 : struct spdk_fsdev_file_object *fobject;
316 : struct spdk_fsdev_file_handle *fhandle;
317 : size_t size;
318 : uint64_t offs;
319 : uint64_t flags;
320 : const struct iovec *iov;
321 : uint32_t iovcnt;
322 : struct spdk_fsdev_io_opts *opts;
323 : } write;
324 : struct {
325 : struct spdk_fsdev_file_object *fobject;
326 : } statfs;
327 : struct {
328 : struct spdk_fsdev_file_object *fobject;
329 : struct spdk_fsdev_file_handle *fhandle;
330 : } release;
331 : struct {
332 : struct spdk_fsdev_file_object *fobject;
333 : struct spdk_fsdev_file_handle *fhandle;
334 : bool datasync;
335 : } fsync;
336 : struct {
337 : struct spdk_fsdev_file_object *fobject;
338 : char *name;
339 : char *value;
340 : size_t size;
341 : uint32_t flags;
342 : } setxattr;
343 : struct {
344 : struct spdk_fsdev_file_object *fobject;
345 : char *name;
346 : void *buffer;
347 : size_t size;
348 : } getxattr;
349 : struct {
350 : struct spdk_fsdev_file_object *fobject;
351 : char *buffer;
352 : size_t size;
353 : } listxattr;
354 : struct {
355 : struct spdk_fsdev_file_object *fobject;
356 : char *name;
357 : } removexattr;
358 : struct {
359 : struct spdk_fsdev_file_object *fobject;
360 : struct spdk_fsdev_file_handle *fhandle;
361 : } flush;
362 : struct {
363 : struct spdk_fsdev_file_object *fobject;
364 : uint32_t flags;
365 : } opendir;
366 : struct {
367 : struct spdk_fsdev_file_object *fobject;
368 : struct spdk_fsdev_file_handle *fhandle;
369 : uint64_t offset;
370 : int (*entry_cb_fn)(struct spdk_fsdev_io *fsdev_io, void *cb_arg);
371 : spdk_fsdev_readdir_entry_cb *usr_entry_cb_fn;
372 : } readdir;
373 : struct {
374 : struct spdk_fsdev_file_object *fobject;
375 : struct spdk_fsdev_file_handle *fhandle;
376 : } releasedir;
377 : struct {
378 : struct spdk_fsdev_file_object *fobject;
379 : struct spdk_fsdev_file_handle *fhandle;
380 : bool datasync;
381 : } fsyncdir;
382 : struct {
383 : struct spdk_fsdev_file_object *fobject;
384 : struct spdk_fsdev_file_handle *fhandle;
385 : int operation; /* see man flock */
386 : } flock;
387 : struct {
388 : struct spdk_fsdev_file_object *parent_fobject;
389 : char *name;
390 : mode_t mode;
391 : uint32_t flags;
392 : mode_t umask;
393 : uid_t euid;
394 : gid_t egid;
395 : } create;
396 : struct {
397 : uint64_t unique_to_abort;
398 : } abort;
399 : struct {
400 : struct spdk_fsdev_file_object *fobject;
401 : struct spdk_fsdev_file_handle *fhandle;
402 : int mode;
403 : off_t offset;
404 : off_t length;
405 : } fallocate;
406 : struct {
407 : struct spdk_fsdev_file_object *fobject_in;
408 : struct spdk_fsdev_file_handle *fhandle_in;
409 : off_t off_in;
410 : struct spdk_fsdev_file_object *fobject_out;
411 : struct spdk_fsdev_file_handle *fhandle_out;
412 : off_t off_out;
413 : size_t len;
414 : uint32_t flags;
415 : } copy_file_range;
416 : } u_in;
417 :
418 : union {
419 : struct {
420 : struct spdk_fsdev_file_object *fobject;
421 : struct spdk_fsdev_file_attr attr;
422 : } lookup;
423 : struct {
424 : struct spdk_fsdev_file_attr attr;
425 : } getattr;
426 : struct {
427 : struct spdk_fsdev_file_attr attr;
428 : } setattr;
429 : struct {
430 : char *linkname; /* will be freed by the fsdev layer */
431 : } readlink;
432 : struct {
433 : struct spdk_fsdev_file_object *fobject;
434 : struct spdk_fsdev_file_attr attr;
435 : } symlink;
436 : struct {
437 : struct spdk_fsdev_file_object *fobject;
438 : struct spdk_fsdev_file_attr attr;
439 : } mknod;
440 : struct {
441 : struct spdk_fsdev_file_object *fobject;
442 : struct spdk_fsdev_file_attr attr;
443 : } mkdir;
444 : struct {
445 : struct spdk_fsdev_file_object *fobject;
446 : struct spdk_fsdev_file_attr attr;
447 : } link;
448 : struct {
449 : struct spdk_fsdev_file_handle *fhandle;
450 : } open;
451 : struct {
452 : uint32_t data_size;
453 : } read;
454 : struct {
455 : uint32_t data_size;
456 : } write;
457 : struct {
458 : struct spdk_fsdev_file_statfs statfs;
459 : } statfs;
460 : struct {
461 : size_t value_size;
462 : } getxattr;
463 : struct {
464 : size_t data_size;
465 : bool size_only;
466 : } listxattr;
467 : struct {
468 : struct spdk_fsdev_file_handle *fhandle;
469 : } opendir;
470 : struct {
471 : const char *name;
472 : struct spdk_fsdev_file_object *fobject;
473 : struct spdk_fsdev_file_attr attr;
474 : off_t offset;
475 : } readdir;
476 : struct {
477 : struct spdk_fsdev_file_object *fobject;
478 : struct spdk_fsdev_file_handle *fhandle;
479 : struct spdk_fsdev_file_attr attr;
480 : } create;
481 : struct {
482 : size_t data_size;
483 : } copy_file_range;
484 : } u_out;
485 :
486 : /**
487 : * Fields that are used internally by the fsdev subsystem. Fsdev modules
488 : * must not read or write to these fields.
489 : */
490 : struct __fsdev_io_internal_fields {
491 : /** The fsdev I/O channel that this was handled on. */
492 : struct spdk_fsdev_channel *ch;
493 :
494 : /** The fsdev descriptor that was used when submitting this I/O. */
495 : struct spdk_fsdev_desc *desc;
496 :
497 : /** User function that will be called when this completes */
498 : spdk_fsdev_io_completion_cb cb_fn;
499 :
500 : /** Context that will be passed to the completion callback */
501 : void *cb_arg;
502 :
503 : /**
504 : * Set to true while the fsdev module submit_request function is in progress.
505 : *
506 : * This is used to decide whether spdk_fsdev_io_complete() can complete the I/O directly
507 : * or if completion must be deferred via an event.
508 : */
509 : bool in_submit_request;
510 :
511 : /** IO operation */
512 : enum spdk_fsdev_io_type type;
513 :
514 : /** IO unique ID */
515 : uint64_t unique;
516 :
517 : /** User callback */
518 : void *usr_cb_fn;
519 :
520 : /** The context for the user callback */
521 : void *usr_cb_arg;
522 :
523 : /** Status for the IO */
524 : int status;
525 :
526 : /** Member used for linking child I/Os together. */
527 : TAILQ_ENTRY(spdk_fsdev_io) link;
528 :
529 : /** Entry to the list per_thread_cache of struct spdk_fsdev_mgmt_channel. */
530 : STAILQ_ENTRY(spdk_fsdev_io) buf_link;
531 :
532 : /** Entry to the list io_submitted of struct spdk_fsdev_channel */
533 : TAILQ_ENTRY(spdk_fsdev_io) ch_link;
534 : } internal;
535 :
536 : /**
537 : * Per I/O context for use by the fsdev module.
538 : */
539 : uint8_t driver_ctx[0];
540 :
541 : /* No members may be added after driver_ctx! */
542 : };
543 :
544 : /**
545 : * Register a new fsdev.
546 : *
547 : * \param fsdev Filesystem device to register.
548 : *
549 : * \return 0 on success.
550 : * \return -EINVAL if the fsdev name is NULL.
551 : * \return -EEXIST if a fsdev with the same name already exists.
552 : */
553 : int spdk_fsdev_register(struct spdk_fsdev *fsdev);
554 :
555 : /**
556 : * Start unregistering a fsdev. This will notify each currently open descriptor
557 : * on this fsdev of the hotremoval to request the upper layers to stop using this fsdev
558 : * and manually close all the descriptors with spdk_fsdev_close().
559 : * The actual fsdev unregistration may be deferred until all descriptors are closed.
560 : *
561 : * Note: spdk_fsdev_unregister() can be unsafe unless the fsdev is not opened before and
562 : * closed after unregistration. It is recommended to use spdk_fsdev_unregister_by_name().
563 : *
564 : * \param fsdev Filesystem device to unregister.
565 : * \param cb_fn Callback function to be called when the unregister is complete.
566 : * \param cb_arg Argument to be supplied to cb_fn
567 : */
568 : void spdk_fsdev_unregister(struct spdk_fsdev *fsdev, spdk_fsdev_unregister_cb cb_fn, void *cb_arg);
569 :
570 : /**
571 : * Start unregistering a fsdev. This will notify each currently open descriptor
572 : * on this fsdev of the hotremoval to request the upper layer to stop using this fsdev
573 : * and manually close all the descriptors with spdk_fsdev_close().
574 : * The actual fsdev unregistration may be deferred until all descriptors are closed.
575 : *
576 : * \param fsdev_name Filesystem device name to unregister.
577 : * \param module Module by which the filesystem device was registered.
578 : * \param cb_fn Callback function to be called when the unregister is complete.
579 : * \param cb_arg Argument to be supplied to cb_fn
580 : *
581 : * \return 0 on success, or suitable errno value otherwise
582 : */
583 : int spdk_fsdev_unregister_by_name(const char *fsdev_name, struct spdk_fsdev_module *module,
584 : spdk_fsdev_unregister_cb cb_fn, void *cb_arg);
585 :
586 : /**
587 : * Invokes the unregister callback of a fsdev backing a virtual fsdev.
588 : *
589 : * A Fsdev with an asynchronous destruct path should return 1 from its
590 : * destruct function and call this function at the conclusion of that path.
591 : * Fsdevs with synchronous destruct paths should return 0 from their destruct
592 : * path.
593 : *
594 : * \param fsdev Filesystem device that was destroyed.
595 : * \param fsdeverrno Error code returned from fsdev's destruct callback.
596 : */
597 : void spdk_fsdev_destruct_done(struct spdk_fsdev *fsdev, int fsdeverrno);
598 :
599 : /**
600 : * Indicate to the fsdev layer that the module is done initializing.
601 : *
602 : * To be called once during module_init or asynchronously after
603 : * an asynchronous operation required for module initialization is completed.
604 : *
605 : * \param module Pointer to the module completing the initialization.
606 : */
607 : void spdk_fsdev_module_init_done(struct spdk_fsdev_module *module);
608 :
609 : /**
610 : * Complete a fsdev_io
611 : *
612 : * \param fsdev_io I/O to complete.
613 : * \param status The I/O completion status.
614 : */
615 : void spdk_fsdev_io_complete(struct spdk_fsdev_io *fsdev_io, int status);
616 :
617 :
618 : /**
619 : * Get I/O type
620 : *
621 : * \param fsdev_io I/O to complete.
622 : *
623 : * \return operation code associated with the I/O
624 : */
625 : static inline enum spdk_fsdev_io_type
626 34 : spdk_fsdev_io_get_type(struct spdk_fsdev_io *fsdev_io) {
627 34 : return fsdev_io->internal.type;
628 : }
629 :
630 : /**
631 : * Get I/O unique id
632 : *
633 : * \param fsdev_io I/O to complete.
634 : *
635 : * \return I/O unique id
636 : */
637 : static inline uint64_t
638 34 : spdk_fsdev_io_get_unique(struct spdk_fsdev_io *fsdev_io)
639 : {
640 34 : return fsdev_io->internal.unique;
641 : }
642 :
643 : /**
644 : * Free an I/O request. This should only be called after the completion callback
645 : * for the I/O has been called and notifies the fsdev layer that memory may now
646 : * be released.
647 : *
648 : * \param fsdev_io I/O request.
649 : */
650 : void spdk_fsdev_free_io(struct spdk_fsdev_io *fsdev_io);
651 :
652 :
653 : /**
654 : * Get a thread that given fsdev_io was submitted on.
655 : *
656 : * \param fsdev_io I/O
657 : * \return thread that submitted the I/O
658 : */
659 : struct spdk_thread *spdk_fsdev_io_get_thread(struct spdk_fsdev_io *fsdev_io);
660 :
661 : /**
662 : * Get the fsdev module's I/O channel that the given fsdev_io was submitted on.
663 : *
664 : * \param fsdev_io I/O
665 : * \return the fsdev module's I/O channel that the given fsdev_io was submitted on.
666 : */
667 : struct spdk_io_channel *spdk_fsdev_io_get_io_channel(struct spdk_fsdev_io *fsdev_io);
668 :
669 : /**
670 : * Add the given module to the list of registered modules.
671 : * This function should be invoked by referencing the macro
672 : * SPDK_FSDEV_MODULE_REGISTER in the module c file.
673 : *
674 : * \param fsdev_module Module to be added.
675 : */
676 : void spdk_fsdev_module_list_add(struct spdk_fsdev_module *fsdev_module);
677 :
678 : /**
679 : * Find registered module with name pointed by \c name.
680 : *
681 : * \param name name of module to be searched for.
682 : * \return pointer to module or NULL if no module with \c name exist
683 : */
684 : struct spdk_fsdev_module *spdk_fsdev_module_list_find(const char *name);
685 :
686 : static inline struct spdk_fsdev_io *
687 : spdk_fsdev_io_from_ctx(void *ctx)
688 : {
689 : return SPDK_CONTAINEROF(ctx, struct spdk_fsdev_io, driver_ctx);
690 : }
691 :
692 : /*
693 : * Macro used to register module for later initialization.
694 : */
695 : #define SPDK_FSDEV_MODULE_REGISTER(name, module) \
696 : static void __attribute__((constructor)) _spdk_fsdev_module_register_##name(void) \
697 : { \
698 : spdk_fsdev_module_list_add(module); \
699 : }
700 :
701 : #ifdef __cplusplus
702 : }
703 : #endif
704 :
705 : #endif /* SPDK_FSDEV_MODULE_H */
|