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