4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 /* We extend the generic backend struct with extra fields relating
47 struct backend_filter
{
48 struct backend backend
;
49 struct nbdkit_filter filter
;
52 /* Note this frees the whole chain. */
54 filter_free (struct backend
*b
)
56 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
58 b
->next
->free (b
->next
);
60 backend_unload (b
, f
->filter
.unload
);
65 filter_thread_model (struct backend
*b
)
67 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
68 int filter_thread_model
= NBDKIT_THREAD_MODEL_PARALLEL
;
69 int model
= b
->next
->thread_model (b
->next
);
71 if (f
->filter
.thread_model
) {
72 filter_thread_model
= f
->filter
.thread_model ();
73 if (filter_thread_model
== -1)
77 if (filter_thread_model
< model
) /* more serialized */
78 model
= filter_thread_model
;
83 /* This is actually passing the request through to the final plugin,
84 * hence the function name.
87 plugin_name (struct backend
*b
)
89 return b
->next
->plugin_name (b
->next
);
93 filter_version (struct backend
*b
)
95 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
97 return f
->filter
._version
;
101 filter_usage (struct backend
*b
)
103 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
106 printf ("filter: %s", b
->name
);
107 if (f
->filter
.longname
)
108 printf (" (%s)", f
->filter
.longname
);
110 printf ("(%s)\n", b
->filename
);
111 if (f
->filter
.description
) {
112 printf ("%s", f
->filter
.description
);
113 if ((p
= strrchr (f
->filter
.description
, '\n')) == NULL
|| p
[1])
116 if (f
->filter
.config_help
) {
117 printf ("%s", f
->filter
.config_help
);
118 if ((p
= strrchr (f
->filter
.config_help
, '\n')) == NULL
|| p
[1])
124 filter_dump_fields (struct backend
*b
)
126 b
->next
->dump_fields (b
->next
);
130 next_config (struct backend
*b
, const char *key
, const char *value
)
132 b
->config (b
, key
, value
);
137 filter_config (struct backend
*b
, const char *key
, const char *value
)
139 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
141 debug ("%s: config key=%s, value=%s",
142 b
->name
, key
, value
);
144 if (f
->filter
.config
) {
145 if (f
->filter
.config (next_config
, b
->next
, key
, value
) == -1)
149 b
->next
->config (b
->next
, key
, value
);
153 next_config_complete (struct backend
*b
)
155 b
->config_complete (b
);
160 filter_config_complete (struct backend
*b
)
162 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
164 debug ("%s: config_complete", b
->name
);
166 if (f
->filter
.config_complete
) {
167 if (f
->filter
.config_complete (next_config_complete
, b
->next
) == -1)
171 b
->next
->config_complete (b
->next
);
175 filter_get_ready (struct backend
*b
)
177 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
179 b
->next
->get_ready (b
->next
); /* exits on failure */
181 debug ("%s: get_ready thread_model=%d", b
->name
, thread_model
);
183 if (f
->filter
.get_ready
) {
184 if (f
->filter
.get_ready (thread_model
) == -1)
190 filter_after_fork (struct backend
*b
)
192 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
194 b
->next
->after_fork (b
->next
); /* exits on failure */
196 debug ("%s: after_fork", b
->name
);
198 if (f
->filter
.after_fork
) {
199 if (f
->filter
.after_fork (b
->next
) == -1)
205 filter_cleanup (struct backend
*b
)
207 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
209 debug ("%s: cleanup", b
->name
);
210 if (f
->filter
.cleanup
)
211 f
->filter
.cleanup (b
->next
);
213 b
->next
->cleanup (b
->next
);
217 filter_preconnect (struct backend
*b
, int readonly
)
219 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
221 debug ("%s: preconnect", b
->name
);
223 if (f
->filter
.preconnect
)
224 return f
->filter
.preconnect (b
->next
->preconnect
, b
->next
, readonly
);
226 return b
->next
->preconnect (b
->next
, readonly
);
229 /* magic_config_key only applies to plugins, so this passes the
230 * request through to the plugin (hence the name).
233 plugin_magic_config_key (struct backend
*b
)
235 return b
->next
->magic_config_key (b
->next
);
239 filter_list_exports (struct backend
*b
, int readonly
, int is_tls
,
240 struct nbdkit_exports
*exports
)
242 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
244 if (f
->filter
.list_exports
)
245 return f
->filter
.list_exports (backend_list_exports
, b
->next
,
246 readonly
, is_tls
, exports
);
247 return backend_list_exports (b
->next
, readonly
, exports
);
251 filter_default_export (struct backend
*b
, int readonly
, int is_tls
)
253 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
255 if (f
->filter
.default_export
)
256 return f
->filter
.default_export (backend_default_export
, b
->next
,
258 return backend_default_export (b
->next
, readonly
);
262 next_open (struct context
*c
, int readonly
, const char *exportname
)
264 struct backend
*b
= nbdkit_context_get_backend (c
);
265 struct context
*c_next
= nbdkit_next_context_open (b
, readonly
, exportname
,
271 old
= nbdkit_context_set_next (c
, c_next
);
272 assert (old
== NULL
);
277 filter_open (struct context
*c
, int readonly
, const char *exportname
,
280 struct backend
*b
= c
->b
;
281 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
284 /* Most filters will call next_open first, resulting in
285 * inner-to-outer ordering.
288 handle
= f
->filter
.open (next_open
, c
, readonly
, exportname
,
290 else if (next_open (c
, readonly
, exportname
) == -1)
293 handle
= NBDKIT_HANDLE_NOT_NEEDED
;
298 filter_close (struct context
*c
)
300 struct backend
*b
= c
->b
;
301 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
305 f
->filter
.close (c
->handle
);
309 filter_prepare (struct context
*c
, int readonly
)
311 struct backend
*b
= c
->b
;
312 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
313 struct context
*c_next
= c
->c_next
;
315 if (f
->filter
.prepare
&&
316 f
->filter
.prepare (c_next
, c
->handle
, readonly
) == -1)
323 filter_finalize (struct context
*c
)
325 struct backend
*b
= c
->b
;
326 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
327 struct context
*c_next
= c
->c_next
;
329 if (f
->filter
.finalize
&&
330 f
->filter
.finalize (c_next
, c
->handle
) == -1)
336 filter_export_description (struct context
*c
)
338 struct backend
*b
= c
->b
;
339 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
340 struct context
*c_next
= c
->c_next
;
342 if (f
->filter
.export_description
)
343 return f
->filter
.export_description (c_next
, c
->handle
);
345 return backend_export_description (c_next
);
349 filter_get_size (struct context
*c
)
351 struct backend
*b
= c
->b
;
352 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
353 struct context
*c_next
= c
->c_next
;
355 if (f
->filter
.get_size
)
356 return f
->filter
.get_size (c_next
, c
->handle
);
358 return backend_get_size (c_next
);
362 filter_block_size (struct context
*c
,
363 uint32_t *minimum
, uint32_t *preferred
, uint32_t *maximum
)
365 struct backend
*b
= c
->b
;
366 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
367 struct context
*c_next
= c
->c_next
;
369 if (f
->filter
.block_size
)
370 return f
->filter
.block_size (c_next
, c
->handle
,
371 minimum
, preferred
, maximum
);
373 return backend_block_size (c_next
,
374 minimum
, preferred
, maximum
);
378 filter_can_write (struct context
*c
)
380 struct backend
*b
= c
->b
;
381 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
382 struct context
*c_next
= c
->c_next
;
384 if (f
->filter
.can_write
)
385 return f
->filter
.can_write (c_next
, c
->handle
);
387 return backend_can_write (c_next
);
391 filter_can_flush (struct context
*c
)
393 struct backend
*b
= c
->b
;
394 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
395 struct context
*c_next
= c
->c_next
;
397 if (f
->filter
.can_flush
)
398 return f
->filter
.can_flush (c_next
, c
->handle
);
400 return backend_can_flush (c_next
);
404 filter_is_rotational (struct context
*c
)
406 struct backend
*b
= c
->b
;
407 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
408 struct context
*c_next
= c
->c_next
;
410 if (f
->filter
.is_rotational
)
411 return f
->filter
.is_rotational (c_next
, c
->handle
);
413 return backend_is_rotational (c_next
);
417 filter_can_trim (struct context
*c
)
419 struct backend
*b
= c
->b
;
420 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
421 struct context
*c_next
= c
->c_next
;
423 if (f
->filter
.can_trim
)
424 return f
->filter
.can_trim (c_next
, c
->handle
);
426 return backend_can_trim (c_next
);
430 filter_can_zero (struct context
*c
)
432 struct backend
*b
= c
->b
;
433 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
434 struct context
*c_next
= c
->c_next
;
436 if (f
->filter
.can_zero
)
437 return f
->filter
.can_zero (c_next
, c
->handle
);
439 return backend_can_zero (c_next
);
443 filter_can_fast_zero (struct context
*c
)
445 struct backend
*b
= c
->b
;
446 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
447 struct context
*c_next
= c
->c_next
;
449 if (f
->filter
.can_fast_zero
)
450 return f
->filter
.can_fast_zero (c_next
, c
->handle
);
452 return backend_can_fast_zero (c_next
);
456 filter_can_extents (struct context
*c
)
458 struct backend
*b
= c
->b
;
459 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
460 struct context
*c_next
= c
->c_next
;
462 if (f
->filter
.can_extents
)
463 return f
->filter
.can_extents (c_next
, c
->handle
);
465 return backend_can_extents (c_next
);
469 filter_can_fua (struct context
*c
)
471 struct backend
*b
= c
->b
;
472 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
473 struct context
*c_next
= c
->c_next
;
475 if (f
->filter
.can_fua
)
476 return f
->filter
.can_fua (c_next
, c
->handle
);
478 return backend_can_fua (c_next
);
482 filter_can_multi_conn (struct context
*c
)
484 struct backend
*b
= c
->b
;
485 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
486 struct context
*c_next
= c
->c_next
;
488 if (f
->filter
.can_multi_conn
)
489 return f
->filter
.can_multi_conn (c_next
, c
->handle
);
491 return backend_can_multi_conn (c_next
);
495 filter_can_cache (struct context
*c
)
497 struct backend
*b
= c
->b
;
498 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
499 struct context
*c_next
= c
->c_next
;
501 if (f
->filter
.can_cache
)
502 return f
->filter
.can_cache (c_next
, c
->handle
);
504 return backend_can_cache (c_next
);
508 filter_pread (struct context
*c
,
509 void *buf
, uint32_t count
, uint64_t offset
,
510 uint32_t flags
, int *err
)
512 struct backend
*b
= c
->b
;
513 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
514 struct context
*c_next
= c
->c_next
;
517 return f
->filter
.pread (c_next
, c
->handle
,
518 buf
, count
, offset
, flags
, err
);
520 return backend_pread (c_next
, buf
, count
, offset
, flags
, err
);
524 filter_pwrite (struct context
*c
,
525 const void *buf
, uint32_t count
, uint64_t offset
,
526 uint32_t flags
, int *err
)
528 struct backend
*b
= c
->b
;
529 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
530 struct context
*c_next
= c
->c_next
;
532 if (f
->filter
.pwrite
)
533 return f
->filter
.pwrite (c_next
, c
->handle
,
534 buf
, count
, offset
, flags
, err
);
536 return backend_pwrite (c_next
, buf
, count
, offset
, flags
, err
);
540 filter_flush (struct context
*c
,
541 uint32_t flags
, int *err
)
543 struct backend
*b
= c
->b
;
544 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
545 struct context
*c_next
= c
->c_next
;
548 return f
->filter
.flush (c_next
, c
->handle
, flags
, err
);
550 return backend_flush (c_next
, flags
, err
);
554 filter_trim (struct context
*c
,
555 uint32_t count
, uint64_t offset
,
556 uint32_t flags
, int *err
)
558 struct backend
*b
= c
->b
;
559 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
560 struct context
*c_next
= c
->c_next
;
563 return f
->filter
.trim (c_next
, c
->handle
, count
, offset
,
566 return backend_trim (c_next
, count
, offset
, flags
, err
);
570 filter_zero (struct context
*c
,
571 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
573 struct backend
*b
= c
->b
;
574 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
575 struct context
*c_next
= c
->c_next
;
578 return f
->filter
.zero (c_next
, c
->handle
,
579 count
, offset
, flags
, err
);
581 return backend_zero (c_next
, count
, offset
, flags
, err
);
585 filter_extents (struct context
*c
,
586 uint32_t count
, uint64_t offset
, uint32_t flags
,
587 struct nbdkit_extents
*extents
, int *err
)
589 struct backend
*b
= c
->b
;
590 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
591 struct context
*c_next
= c
->c_next
;
593 if (f
->filter
.extents
)
594 return f
->filter
.extents (c_next
, c
->handle
,
595 count
, offset
, flags
,
598 return backend_extents (c_next
, count
, offset
, flags
,
603 filter_cache (struct context
*c
,
604 uint32_t count
, uint64_t offset
,
605 uint32_t flags
, int *err
)
607 struct backend
*b
= c
->b
;
608 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
609 struct context
*c_next
= c
->c_next
;
612 return f
->filter
.cache (c_next
, c
->handle
,
613 count
, offset
, flags
, err
);
615 return backend_cache (c_next
, count
, offset
, flags
, err
);
618 static struct backend filter_functions
= {
620 .thread_model
= filter_thread_model
,
621 .plugin_name
= plugin_name
,
622 .usage
= filter_usage
,
623 .version
= filter_version
,
624 .dump_fields
= filter_dump_fields
,
625 .config
= filter_config
,
626 .config_complete
= filter_config_complete
,
627 .magic_config_key
= plugin_magic_config_key
,
628 .get_ready
= filter_get_ready
,
629 .after_fork
= filter_after_fork
,
630 .cleanup
= filter_cleanup
,
631 .preconnect
= filter_preconnect
,
632 .list_exports
= filter_list_exports
,
633 .default_export
= filter_default_export
,
635 .prepare
= filter_prepare
,
636 .finalize
= filter_finalize
,
637 .close
= filter_close
,
638 .export_description
= filter_export_description
,
639 .get_size
= filter_get_size
,
640 .block_size
= filter_block_size
,
641 .can_write
= filter_can_write
,
642 .can_flush
= filter_can_flush
,
643 .is_rotational
= filter_is_rotational
,
644 .can_trim
= filter_can_trim
,
645 .can_zero
= filter_can_zero
,
646 .can_fast_zero
= filter_can_fast_zero
,
647 .can_extents
= filter_can_extents
,
648 .can_fua
= filter_can_fua
,
649 .can_multi_conn
= filter_can_multi_conn
,
650 .can_cache
= filter_can_cache
,
651 .pread
= filter_pread
,
652 .pwrite
= filter_pwrite
,
653 .flush
= filter_flush
,
656 .extents
= filter_extents
,
657 .cache
= filter_cache
,
660 /* Register and load a filter. */
662 filter_register (struct backend
*next
, size_t index
, const char *filename
,
663 void *dl
, struct nbdkit_filter
*(*filter_init
) (void))
665 struct backend_filter
*f
;
666 const struct nbdkit_filter
*filter
;
668 f
= calloc (1, sizeof *f
);
674 f
->backend
= filter_functions
;
675 backend_init (&f
->backend
, next
, index
, filename
, dl
, "filter");
677 /* Call the initialization function which returns the address of the
678 * filter's own 'struct nbdkit_filter'.
680 filter
= filter_init ();
682 fprintf (stderr
, "%s: %s: filter registration function failed\n",
683 program_name
, filename
);
687 /* We do not provide API or ABI guarantees for filters, other than
688 * the ABI position and API contents of _api_version and _version to
689 * diagnose mismatch from the current nbdkit version.
691 if (filter
->_api_version
!= NBDKIT_FILTER_API_VERSION
) {
693 "%s: %s: filter is incompatible with this version of nbdkit "
694 "(_api_version = %d, need %d)\n",
695 program_name
, filename
, filter
->_api_version
,
696 NBDKIT_FILTER_API_VERSION
);
699 if (filter
->_version
== NULL
||
700 strcmp (filter
->_version
, PACKAGE_VERSION
) != 0) {
702 "%s: %s: filter is incompatible with this version of nbdkit "
703 "(_version = %s, need %s)\n",
704 program_name
, filename
, filter
->_version
?: "<null>",
711 backend_load (&f
->backend
, f
->filter
.name
, f
->filter
.load
);
713 return (struct backend
*) f
;
716 NBDKIT_DLL_PUBLIC
struct backend
*
717 nbdkit_context_get_backend (struct context
*c
)
723 NBDKIT_DLL_PUBLIC
struct context
*
724 nbdkit_next_context_open (struct backend
*b
,
725 int readonly
, const char *exportname
, int shared
)
727 struct context
*c
= threadlocal_get_context ();
730 assert (!c
|| b
== c
->b
->next
);
731 return backend_open (b
, readonly
, exportname
, shared
|| !c
|| !c
->conn
);
734 NBDKIT_DLL_PUBLIC
void
735 nbdkit_next_context_close (struct context
*c
)
741 NBDKIT_DLL_PUBLIC
struct context
*
742 nbdkit_context_set_next (struct context
*c
, struct context
*next
)
748 assert (next
->b
== c
->b
->next
);