Update Red Hat Copyright Notices
[nbdkit.git] / server / filters.c
blobf32a9b46f6f2fea3c666abd52fa86e094bb353be
1 /* nbdkit
2 * Copyright Red Hat
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
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
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <inttypes.h>
40 #include <assert.h>
42 #include "internal.h"
44 /* We extend the generic backend struct with extra fields relating
45 * to this filter.
47 struct backend_filter {
48 struct backend backend;
49 struct nbdkit_filter filter;
52 /* Note this frees the whole chain. */
53 static void
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);
61 free (f);
64 static int
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)
74 exit (EXIT_FAILURE);
77 if (filter_thread_model < model) /* more serialized */
78 model = filter_thread_model;
80 return model;
83 /* This is actually passing the request through to the final plugin,
84 * hence the function name.
86 static const char *
87 plugin_name (struct backend *b)
89 return b->next->plugin_name (b->next);
92 static const char *
93 filter_version (struct backend *b)
95 struct backend_filter *f = container_of (b, struct backend_filter, backend);
97 return f->filter._version;
100 static void
101 filter_usage (struct backend *b)
103 struct backend_filter *f = container_of (b, struct backend_filter, backend);
104 const char *p;
106 printf ("filter: %s", b->name);
107 if (f->filter.longname)
108 printf (" (%s)", f->filter.longname);
109 printf ("\n");
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])
114 printf ("\n");
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])
119 printf ("\n");
123 static void
124 filter_dump_fields (struct backend *b)
126 b->next->dump_fields (b->next);
129 static int
130 next_config (struct backend *b, const char *key, const char *value)
132 b->config (b, key, value);
133 return 0;
136 static void
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)
146 exit (EXIT_FAILURE);
148 else
149 b->next->config (b->next, key, value);
152 static int
153 next_config_complete (struct backend *b)
155 b->config_complete (b);
156 return 0;
159 static void
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)
168 exit (EXIT_FAILURE);
170 else
171 b->next->config_complete (b->next);
174 static void
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)
185 exit (EXIT_FAILURE);
189 static void
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)
200 exit (EXIT_FAILURE);
204 static void
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);
216 static int
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);
225 else
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).
232 static const char *
233 plugin_magic_config_key (struct backend *b)
235 return b->next->magic_config_key (b->next);
238 static int
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);
250 static const char *
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,
257 readonly, is_tls);
258 return backend_default_export (b->next, readonly);
261 static int
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,
266 false);
267 struct context *old;
269 if (c_next == NULL)
270 return -1;
271 old = nbdkit_context_set_next (c, c_next);
272 assert (old == NULL);
273 return 0;
276 static void *
277 filter_open (struct context *c, int readonly, const char *exportname,
278 int is_tls)
280 struct backend *b = c->b;
281 struct backend_filter *f = container_of (b, struct backend_filter, backend);
282 void *handle;
284 /* Most filters will call next_open first, resulting in
285 * inner-to-outer ordering.
287 if (f->filter.open)
288 handle = f->filter.open (next_open, c, readonly, exportname,
289 is_tls);
290 else if (next_open (c, readonly, exportname) == -1)
291 handle = NULL;
292 else
293 handle = NBDKIT_HANDLE_NOT_NEEDED;
294 return handle;
297 static void
298 filter_close (struct context *c)
300 struct backend *b = c->b;
301 struct backend_filter *f = container_of (b, struct backend_filter, backend);
303 assert (c->handle);
304 if (f->filter.close)
305 f->filter.close (c->handle);
308 static int
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)
317 return -1;
319 return 0;
322 static int
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)
331 return -1;
332 return 0;
335 static const char *
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);
344 else
345 return backend_export_description (c_next);
348 static int64_t
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);
357 else
358 return backend_get_size (c_next);
361 static int
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);
372 else
373 return backend_block_size (c_next,
374 minimum, preferred, maximum);
377 static int
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);
386 else
387 return backend_can_write (c_next);
390 static int
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);
399 else
400 return backend_can_flush (c_next);
403 static int
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);
412 else
413 return backend_is_rotational (c_next);
416 static int
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);
425 else
426 return backend_can_trim (c_next);
429 static int
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);
438 else
439 return backend_can_zero (c_next);
442 static int
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);
451 else
452 return backend_can_fast_zero (c_next);
455 static int
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);
464 else
465 return backend_can_extents (c_next);
468 static int
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);
477 else
478 return backend_can_fua (c_next);
481 static int
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);
490 else
491 return backend_can_multi_conn (c_next);
494 static int
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);
503 else
504 return backend_can_cache (c_next);
507 static int
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;
516 if (f->filter.pread)
517 return f->filter.pread (c_next, c->handle,
518 buf, count, offset, flags, err);
519 else
520 return backend_pread (c_next, buf, count, offset, flags, err);
523 static int
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);
535 else
536 return backend_pwrite (c_next, buf, count, offset, flags, err);
539 static int
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;
547 if (f->filter.flush)
548 return f->filter.flush (c_next, c->handle, flags, err);
549 else
550 return backend_flush (c_next, flags, err);
553 static int
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;
562 if (f->filter.trim)
563 return f->filter.trim (c_next, c->handle, count, offset,
564 flags, err);
565 else
566 return backend_trim (c_next, count, offset, flags, err);
569 static int
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;
577 if (f->filter.zero)
578 return f->filter.zero (c_next, c->handle,
579 count, offset, flags, err);
580 else
581 return backend_zero (c_next, count, offset, flags, err);
584 static int
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,
596 extents, err);
597 else
598 return backend_extents (c_next, count, offset, flags,
599 extents, err);
602 static int
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;
611 if (f->filter.cache)
612 return f->filter.cache (c_next, c->handle,
613 count, offset, flags, err);
614 else
615 return backend_cache (c_next, count, offset, flags, err);
618 static struct backend filter_functions = {
619 .free = filter_free,
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,
634 .open = filter_open,
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,
654 .trim = filter_trim,
655 .zero = filter_zero,
656 .extents = filter_extents,
657 .cache = filter_cache,
660 /* Register and load a filter. */
661 struct backend *
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);
669 if (f == NULL) {
670 perror ("strdup");
671 exit (EXIT_FAILURE);
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 ();
681 if (!filter) {
682 fprintf (stderr, "%s: %s: filter registration function failed\n",
683 program_name, filename);
684 exit (EXIT_FAILURE);
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) {
692 fprintf (stderr,
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);
697 exit (EXIT_FAILURE);
699 if (filter->_version == NULL ||
700 strcmp (filter->_version, PACKAGE_VERSION) != 0) {
701 fprintf (stderr,
702 "%s: %s: filter is incompatible with this version of nbdkit "
703 "(_version = %s, need %s)\n",
704 program_name, filename, filter->_version ?: "<null>",
705 PACKAGE_VERSION);
706 exit (EXIT_FAILURE);
709 f->filter = *filter;
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)
719 assert (c);
720 return c->b->next;
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 ();
729 assert (b);
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)
737 if (c)
738 backend_close (c);
741 NBDKIT_DLL_PUBLIC struct context *
742 nbdkit_context_set_next (struct context *c, struct context *next)
744 struct context *old;
746 assert (c);
747 if (next)
748 assert (next->b == c->b->next);
749 old = c->c_next;
750 c->c_next = next;
751 return old;