backend: Implement next_ops->reopen call.
[nbdkit/ericb.git] / server / filters.c
blob78e32bc5b625687a8b8f74685ea1b0c8429bace0
1 /* nbdkit
2 * Copyright (C) 2013-2019 Red Hat Inc.
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 /* Literally a backend + a connection pointer. This is the
53 * implementation of ‘void *nxdata’ in the filter API.
55 struct b_conn {
56 struct backend *b;
57 struct connection *conn;
60 /* Note this frees the whole chain. */
61 static void
62 filter_free (struct backend *b)
64 struct backend_filter *f = container_of (b, struct backend_filter, backend);
66 b->next->free (b->next);
68 backend_unload (b, f->filter.unload);
69 free (f);
72 static int
73 filter_thread_model (struct backend *b)
75 struct backend_filter *f = container_of (b, struct backend_filter, backend);
76 int filter_thread_model = NBDKIT_THREAD_MODEL_PARALLEL;
77 int thread_model = b->next->thread_model (b->next);
79 if (f->filter.thread_model) {
80 filter_thread_model = f->filter.thread_model ();
81 if (filter_thread_model == -1)
82 exit (EXIT_FAILURE);
85 if (filter_thread_model < thread_model) /* more serialized */
86 thread_model = filter_thread_model;
88 return thread_model;
91 /* This is actually passing the request through to the final plugin,
92 * hence the function name.
94 static const char *
95 plugin_name (struct backend *b)
97 return b->next->plugin_name (b->next);
100 static const char *
101 filter_version (struct backend *b)
103 struct backend_filter *f = container_of (b, struct backend_filter, backend);
105 return f->filter._version;
108 static void
109 filter_usage (struct backend *b)
111 struct backend_filter *f = container_of (b, struct backend_filter, backend);
112 const char *p;
114 printf ("filter: %s", b->name);
115 if (f->filter.longname)
116 printf (" (%s)", f->filter.longname);
117 printf ("\n");
118 printf ("(%s)\n", b->filename);
119 if (f->filter.description) {
120 printf ("%s", f->filter.description);
121 if ((p = strrchr (f->filter.description, '\n')) == NULL || p[1])
122 printf ("\n");
124 if (f->filter.config_help) {
125 printf ("%s", f->filter.config_help);
126 if ((p = strrchr (f->filter.config_help, '\n')) == NULL || p[1])
127 printf ("\n");
131 static void
132 filter_dump_fields (struct backend *b)
134 b->next->dump_fields (b->next);
137 static int
138 next_config (void *nxdata, const char *key, const char *value)
140 struct backend *b = nxdata;
141 b->config (b, key, value);
142 return 0;
145 static void
146 filter_config (struct backend *b, const char *key, const char *value)
148 struct backend_filter *f = container_of (b, struct backend_filter, backend);
150 debug ("%s: config key=%s, value=%s",
151 b->name, key, value);
153 if (f->filter.config) {
154 if (f->filter.config (next_config, b->next, key, value) == -1)
155 exit (EXIT_FAILURE);
157 else
158 b->next->config (b->next, key, value);
161 static int
162 next_config_complete (void *nxdata)
164 struct backend *b = nxdata;
165 b->config_complete (b);
166 return 0;
169 static void
170 filter_config_complete (struct backend *b)
172 struct backend_filter *f = container_of (b, struct backend_filter, backend);
174 debug ("%s: config_complete", b->name);
176 if (f->filter.config_complete) {
177 if (f->filter.config_complete (next_config_complete, b->next) == -1)
178 exit (EXIT_FAILURE);
180 else
181 b->next->config_complete (b->next);
184 /* magic_config_key only applies to plugins, so this passes the
185 * request through to the plugin (hence the name).
187 static const char *
188 plugin_magic_config_key (struct backend *b)
190 return b->next->magic_config_key (b->next);
193 static int
194 next_open (void *nxdata, int readonly)
196 struct b_conn *b_conn = nxdata;
198 return backend_open (b_conn->b, b_conn->conn, readonly);
201 static int
202 filter_open (struct backend *b, struct connection *conn, int readonly)
204 struct backend_filter *f = container_of (b, struct backend_filter, backend);
205 struct b_conn nxdata = { .b = b->next, .conn = conn };
206 void *handle;
208 if (f->filter.open) {
209 handle = f->filter.open (next_open, &nxdata, readonly);
210 if (handle == NULL)
211 return -1;
212 backend_set_handle (b, conn, handle);
214 else {
215 if (backend_open (b->next, conn, readonly) == -1)
216 return -1;
217 backend_set_handle (b, conn, NBDKIT_HANDLE_NOT_NEEDED);
219 return 0;
222 static void
223 filter_close (struct backend *b, struct connection *conn)
225 struct backend_filter *f = container_of (b, struct backend_filter, backend);
226 void *handle = connection_get_handle (conn, b->i);
228 if (handle && f->filter.close)
229 f->filter.close (handle);
230 backend_close (b->next, conn);
233 /* The next_functions structure contains pointers to backend
234 * functions. However because these functions are all expecting a
235 * backend and a connection, we cannot call them directly, but must
236 * write some next_* functions that unpack the two parameters from a
237 * single ‘void *nxdata’ struct pointer (‘b_conn’).
240 static int
241 next_reopen (void *nxdata, int readonly)
243 struct b_conn *b_conn = nxdata;
244 return backend_reopen (b_conn->b, b_conn->conn, readonly);
247 static int64_t
248 next_get_size (void *nxdata)
250 struct b_conn *b_conn = nxdata;
251 return backend_get_size (b_conn->b, b_conn->conn);
254 static int
255 next_can_write (void *nxdata)
257 struct b_conn *b_conn = nxdata;
258 return backend_can_write (b_conn->b, b_conn->conn);
261 static int
262 next_can_flush (void *nxdata)
264 struct b_conn *b_conn = nxdata;
265 return backend_can_flush (b_conn->b, b_conn->conn);
268 static int
269 next_is_rotational (void *nxdata)
271 struct b_conn *b_conn = nxdata;
272 return backend_is_rotational (b_conn->b, b_conn->conn);
275 static int
276 next_can_trim (void *nxdata)
278 struct b_conn *b_conn = nxdata;
279 return backend_can_trim (b_conn->b, b_conn->conn);
282 static int
283 next_can_zero (void *nxdata)
285 struct b_conn *b_conn = nxdata;
286 return backend_can_zero (b_conn->b, b_conn->conn);
289 static int
290 next_can_fast_zero (void *nxdata)
292 struct b_conn *b_conn = nxdata;
293 return backend_can_fast_zero (b_conn->b, b_conn->conn);
296 static int
297 next_can_extents (void *nxdata)
299 struct b_conn *b_conn = nxdata;
300 return backend_can_extents (b_conn->b, b_conn->conn);
303 static int
304 next_can_fua (void *nxdata)
306 struct b_conn *b_conn = nxdata;
307 return backend_can_fua (b_conn->b, b_conn->conn);
310 static int
311 next_can_multi_conn (void *nxdata)
313 struct b_conn *b_conn = nxdata;
314 return backend_can_multi_conn (b_conn->b, b_conn->conn);
317 static int
318 next_can_cache (void *nxdata)
320 struct b_conn *b_conn = nxdata;
321 return backend_can_cache (b_conn->b, b_conn->conn);
324 static int
325 next_pread (void *nxdata, void *buf, uint32_t count, uint64_t offset,
326 uint32_t flags, int *err)
328 struct b_conn *b_conn = nxdata;
329 return backend_pread (b_conn->b, b_conn->conn, buf, count, offset, flags,
330 err);
333 static int
334 next_pwrite (void *nxdata, const void *buf, uint32_t count, uint64_t offset,
335 uint32_t flags, int *err)
337 struct b_conn *b_conn = nxdata;
338 return backend_pwrite (b_conn->b, b_conn->conn, buf, count, offset, flags,
339 err);
342 static int
343 next_flush (void *nxdata, uint32_t flags, int *err)
345 struct b_conn *b_conn = nxdata;
346 return backend_flush (b_conn->b, b_conn->conn, flags, err);
349 static int
350 next_trim (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
351 int *err)
353 struct b_conn *b_conn = nxdata;
354 return backend_trim (b_conn->b, b_conn->conn, count, offset, flags, err);
357 static int
358 next_zero (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
359 int *err)
361 struct b_conn *b_conn = nxdata;
362 return backend_zero (b_conn->b, b_conn->conn, count, offset, flags, err);
365 static int
366 next_extents (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
367 struct nbdkit_extents *extents, int *err)
369 struct b_conn *b_conn = nxdata;
370 return backend_extents (b_conn->b, b_conn->conn, count, offset, flags,
371 extents, err);
374 static int
375 next_cache (void *nxdata, uint32_t count, uint64_t offset,
376 uint32_t flags, int *err)
378 struct b_conn *b_conn = nxdata;
379 return backend_cache (b_conn->b, b_conn->conn, count, offset, flags, err);
382 static struct nbdkit_next_ops next_ops = {
383 .reopen = next_reopen,
384 .get_size = next_get_size,
385 .can_write = next_can_write,
386 .can_flush = next_can_flush,
387 .is_rotational = next_is_rotational,
388 .can_trim = next_can_trim,
389 .can_zero = next_can_zero,
390 .can_fast_zero = next_can_fast_zero,
391 .can_extents = next_can_extents,
392 .can_fua = next_can_fua,
393 .can_multi_conn = next_can_multi_conn,
394 .can_cache = next_can_cache,
395 .pread = next_pread,
396 .pwrite = next_pwrite,
397 .flush = next_flush,
398 .trim = next_trim,
399 .zero = next_zero,
400 .extents = next_extents,
401 .cache = next_cache,
404 static int
405 filter_prepare (struct backend *b, struct connection *conn, int readonly)
407 struct backend_filter *f = container_of (b, struct backend_filter, backend);
408 void *handle = connection_get_handle (conn, b->i);
409 struct b_conn nxdata = { .b = b->next, .conn = conn };
411 /* Call these in order starting from the filter closest to the
412 * plugin.
414 if (backend_prepare (b->next, conn) == -1)
415 return -1;
417 if (f->filter.prepare &&
418 f->filter.prepare (&next_ops, &nxdata, handle, readonly) == -1)
419 return -1;
421 return 0;
424 static int
425 filter_finalize (struct backend *b, struct connection *conn)
427 struct backend_filter *f = container_of (b, struct backend_filter, backend);
428 void *handle = connection_get_handle (conn, b->i);
429 struct b_conn nxdata = { .b = b->next, .conn = conn };
431 debug ("%s: finalize", b->name);
433 /* Call these in reverse order to .prepare above, starting from the
434 * filter furthest away from the plugin.
436 if (f->filter.finalize &&
437 f->filter.finalize (&next_ops, &nxdata, handle) == -1)
438 return -1;
440 return b->next->finalize (b->next, conn);
443 static int64_t
444 filter_get_size (struct backend *b, struct connection *conn)
446 struct backend_filter *f = container_of (b, struct backend_filter, backend);
447 void *handle = connection_get_handle (conn, b->i);
448 struct b_conn nxdata = { .b = b->next, .conn = conn };
450 if (f->filter.get_size)
451 return f->filter.get_size (&next_ops, &nxdata, handle);
452 else
453 return backend_get_size (b->next, conn);
456 static int
457 filter_can_write (struct backend *b, struct connection *conn)
459 struct backend_filter *f = container_of (b, struct backend_filter, backend);
460 void *handle = connection_get_handle (conn, b->i);
461 struct b_conn nxdata = { .b = b->next, .conn = conn };
463 if (f->filter.can_write)
464 return f->filter.can_write (&next_ops, &nxdata, handle);
465 else
466 return backend_can_write (b->next, conn);
469 static int
470 filter_can_flush (struct backend *b, struct connection *conn)
472 struct backend_filter *f = container_of (b, struct backend_filter, backend);
473 void *handle = connection_get_handle (conn, b->i);
474 struct b_conn nxdata = { .b = b->next, .conn = conn };
476 if (f->filter.can_flush)
477 return f->filter.can_flush (&next_ops, &nxdata, handle);
478 else
479 return backend_can_flush (b->next, conn);
482 static int
483 filter_is_rotational (struct backend *b, struct connection *conn)
485 struct backend_filter *f = container_of (b, struct backend_filter, backend);
486 void *handle = connection_get_handle (conn, b->i);
487 struct b_conn nxdata = { .b = b->next, .conn = conn };
489 if (f->filter.is_rotational)
490 return f->filter.is_rotational (&next_ops, &nxdata, handle);
491 else
492 return backend_is_rotational (b->next, conn);
495 static int
496 filter_can_trim (struct backend *b, struct connection *conn)
498 struct backend_filter *f = container_of (b, struct backend_filter, backend);
499 void *handle = connection_get_handle (conn, b->i);
500 struct b_conn nxdata = { .b = b->next, .conn = conn };
502 if (f->filter.can_trim)
503 return f->filter.can_trim (&next_ops, &nxdata, handle);
504 else
505 return backend_can_trim (b->next, conn);
508 static int
509 filter_can_zero (struct backend *b, struct connection *conn)
511 struct backend_filter *f = container_of (b, struct backend_filter, backend);
512 void *handle = connection_get_handle (conn, b->i);
513 struct b_conn nxdata = { .b = b->next, .conn = conn };
515 if (f->filter.can_zero)
516 return f->filter.can_zero (&next_ops, &nxdata, handle);
517 else
518 return backend_can_zero (b->next, conn);
521 static int
522 filter_can_fast_zero (struct backend *b, struct connection *conn)
524 struct backend_filter *f = container_of (b, struct backend_filter, backend);
525 void *handle = connection_get_handle (conn, b->i);
526 struct b_conn nxdata = { .b = b->next, .conn = conn };
528 if (f->filter.can_fast_zero)
529 return f->filter.can_fast_zero (&next_ops, &nxdata, handle);
530 else
531 return backend_can_fast_zero (b->next, conn);
534 static int
535 filter_can_extents (struct backend *b, struct connection *conn)
537 struct backend_filter *f = container_of (b, struct backend_filter, backend);
538 void *handle = connection_get_handle (conn, b->i);
539 struct b_conn nxdata = { .b = b->next, .conn = conn };
541 if (f->filter.can_extents)
542 return f->filter.can_extents (&next_ops, &nxdata, handle);
543 else
544 return backend_can_extents (b->next, conn);
547 static int
548 filter_can_fua (struct backend *b, struct connection *conn)
550 struct backend_filter *f = container_of (b, struct backend_filter, backend);
551 void *handle = connection_get_handle (conn, b->i);
552 struct b_conn nxdata = { .b = b->next, .conn = conn };
554 if (f->filter.can_fua)
555 return f->filter.can_fua (&next_ops, &nxdata, handle);
556 else
557 return backend_can_fua (b->next, conn);
560 static int
561 filter_can_multi_conn (struct backend *b, struct connection *conn)
563 struct backend_filter *f = container_of (b, struct backend_filter, backend);
564 void *handle = connection_get_handle (conn, b->i);
565 struct b_conn nxdata = { .b = b->next, .conn = conn };
567 if (f->filter.can_multi_conn)
568 return f->filter.can_multi_conn (&next_ops, &nxdata, handle);
569 else
570 return backend_can_multi_conn (b->next, conn);
573 static int
574 filter_can_cache (struct backend *b, struct connection *conn)
576 struct backend_filter *f = container_of (b, struct backend_filter, backend);
577 void *handle = connection_get_handle (conn, b->i);
578 struct b_conn nxdata = { .b = b->next, .conn = conn };
580 if (f->filter.can_cache)
581 return f->filter.can_cache (&next_ops, &nxdata, handle);
582 else
583 return backend_can_cache (b->next, conn);
586 static int
587 filter_pread (struct backend *b, struct connection *conn,
588 void *buf, uint32_t count, uint64_t offset,
589 uint32_t flags, int *err)
591 struct backend_filter *f = container_of (b, struct backend_filter, backend);
592 void *handle = connection_get_handle (conn, b->i);
593 struct b_conn nxdata = { .b = b->next, .conn = conn };
595 if (f->filter.pread)
596 return f->filter.pread (&next_ops, &nxdata, handle,
597 buf, count, offset, flags, err);
598 else
599 return backend_pread (b->next, conn, buf, count, offset, flags, err);
602 static int
603 filter_pwrite (struct backend *b, struct connection *conn,
604 const void *buf, uint32_t count, uint64_t offset,
605 uint32_t flags, int *err)
607 struct backend_filter *f = container_of (b, struct backend_filter, backend);
608 void *handle = connection_get_handle (conn, b->i);
609 struct b_conn nxdata = { .b = b->next, .conn = conn };
611 if (f->filter.pwrite)
612 return f->filter.pwrite (&next_ops, &nxdata, handle,
613 buf, count, offset, flags, err);
614 else
615 return backend_pwrite (b->next, conn, buf, count, offset, flags, err);
618 static int
619 filter_flush (struct backend *b, struct connection *conn, uint32_t flags,
620 int *err)
622 struct backend_filter *f = container_of (b, struct backend_filter, backend);
623 void *handle = connection_get_handle (conn, b->i);
624 struct b_conn nxdata = { .b = b->next, .conn = conn };
626 if (f->filter.flush)
627 return f->filter.flush (&next_ops, &nxdata, handle, flags, err);
628 else
629 return backend_flush (b->next, conn, flags, err);
632 static int
633 filter_trim (struct backend *b, struct connection *conn,
634 uint32_t count, uint64_t offset,
635 uint32_t flags, int *err)
637 struct backend_filter *f = container_of (b, struct backend_filter, backend);
638 void *handle = connection_get_handle (conn, b->i);
639 struct b_conn nxdata = { .b = b->next, .conn = conn };
641 if (f->filter.trim)
642 return f->filter.trim (&next_ops, &nxdata, handle, count, offset, flags,
643 err);
644 else
645 return backend_trim (b->next, conn, count, offset, flags, err);
648 static int
649 filter_zero (struct backend *b, struct connection *conn,
650 uint32_t count, uint64_t offset, uint32_t flags, int *err)
652 struct backend_filter *f = container_of (b, struct backend_filter, backend);
653 void *handle = connection_get_handle (conn, b->i);
654 struct b_conn nxdata = { .b = b->next, .conn = conn };
656 if (f->filter.zero)
657 return f->filter.zero (&next_ops, &nxdata, handle,
658 count, offset, flags, err);
659 else
660 return backend_zero (b->next, conn, count, offset, flags, err);
663 static int
664 filter_extents (struct backend *b, struct connection *conn,
665 uint32_t count, uint64_t offset, uint32_t flags,
666 struct nbdkit_extents *extents, int *err)
668 struct backend_filter *f = container_of (b, struct backend_filter, backend);
669 void *handle = connection_get_handle (conn, b->i);
670 struct b_conn nxdata = { .b = b->next, .conn = conn };
672 if (f->filter.extents)
673 return f->filter.extents (&next_ops, &nxdata, handle,
674 count, offset, flags,
675 extents, err);
676 else
677 return backend_extents (b->next, conn, count, offset, flags,
678 extents, err);
681 static int
682 filter_cache (struct backend *b, struct connection *conn,
683 uint32_t count, uint64_t offset,
684 uint32_t flags, int *err)
686 struct backend_filter *f = container_of (b, struct backend_filter, backend);
687 void *handle = connection_get_handle (conn, b->i);
688 struct b_conn nxdata = { .b = b->next, .conn = conn };
691 if (f->filter.cache)
692 return f->filter.cache (&next_ops, &nxdata, handle,
693 count, offset, flags, err);
694 else
695 return backend_cache (b->next, conn, count, offset, flags, err);
698 static struct backend filter_functions = {
699 .free = filter_free,
700 .thread_model = filter_thread_model,
701 .plugin_name = plugin_name,
702 .usage = filter_usage,
703 .version = filter_version,
704 .dump_fields = filter_dump_fields,
705 .config = filter_config,
706 .config_complete = filter_config_complete,
707 .magic_config_key = plugin_magic_config_key,
708 .open = filter_open,
709 .prepare = filter_prepare,
710 .finalize = filter_finalize,
711 .close = filter_close,
712 .get_size = filter_get_size,
713 .can_write = filter_can_write,
714 .can_flush = filter_can_flush,
715 .is_rotational = filter_is_rotational,
716 .can_trim = filter_can_trim,
717 .can_zero = filter_can_zero,
718 .can_fast_zero = filter_can_fast_zero,
719 .can_extents = filter_can_extents,
720 .can_fua = filter_can_fua,
721 .can_multi_conn = filter_can_multi_conn,
722 .can_cache = filter_can_cache,
723 .pread = filter_pread,
724 .pwrite = filter_pwrite,
725 .flush = filter_flush,
726 .trim = filter_trim,
727 .zero = filter_zero,
728 .extents = filter_extents,
729 .cache = filter_cache,
732 /* Register and load a filter. */
733 struct backend *
734 filter_register (struct backend *next, size_t index, const char *filename,
735 void *dl, struct nbdkit_filter *(*filter_init) (void))
737 struct backend_filter *f;
738 const struct nbdkit_filter *filter;
740 f = calloc (1, sizeof *f);
741 if (f == NULL) {
742 perror ("strdup");
743 exit (EXIT_FAILURE);
746 f->backend = filter_functions;
747 backend_init (&f->backend, next, index, filename, dl, "filter");
749 /* Call the initialization function which returns the address of the
750 * filter's own 'struct nbdkit_filter'.
752 filter = filter_init ();
753 if (!filter) {
754 fprintf (stderr, "%s: %s: filter registration function failed\n",
755 program_name, filename);
756 exit (EXIT_FAILURE);
759 /* We do not provide API or ABI guarantees for filters, other than
760 * the ABI position and API contents of _api_version and _version to
761 * diagnose mismatch from the current nbdkit version.
763 if (filter->_api_version != NBDKIT_FILTER_API_VERSION) {
764 fprintf (stderr,
765 "%s: %s: filter is incompatible with this version of nbdkit "
766 "(_api_version = %d, need %d)\n",
767 program_name, filename, filter->_api_version,
768 NBDKIT_FILTER_API_VERSION);
769 exit (EXIT_FAILURE);
771 if (filter->_version == NULL ||
772 strcmp (filter->_version, PACKAGE_VERSION) != 0) {
773 fprintf (stderr,
774 "%s: %s: filter is incompatible with this version of nbdkit "
775 "(_version = %s, need %s)\n",
776 program_name, filename, filter->_version ?: "<null>",
777 PACKAGE_VERSION);
778 exit (EXIT_FAILURE);
781 f->filter = *filter;
783 backend_load (&f->backend, f->filter.name, f->filter.load);
785 return (struct backend *) f;