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
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 /* Literally a backend + a connection pointer. This is the
53 * implementation of ‘void *nxdata’ in the filter API.
57 struct connection
*conn
;
60 /* Note this frees the whole chain. */
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
);
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)
85 if (filter_thread_model
< thread_model
) /* more serialized */
86 thread_model
= filter_thread_model
;
91 /* This is actually passing the request through to the final plugin,
92 * hence the function name.
95 plugin_name (struct backend
*b
)
97 return b
->next
->plugin_name (b
->next
);
101 filter_version (struct backend
*b
)
103 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
105 return f
->filter
._version
;
109 filter_usage (struct backend
*b
)
111 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
114 printf ("filter: %s", b
->name
);
115 if (f
->filter
.longname
)
116 printf (" (%s)", f
->filter
.longname
);
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])
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])
132 filter_dump_fields (struct backend
*b
)
134 b
->next
->dump_fields (b
->next
);
138 next_config (void *nxdata
, const char *key
, const char *value
)
140 struct backend
*b
= nxdata
;
141 b
->config (b
, key
, value
);
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)
158 b
->next
->config (b
->next
, key
, value
);
162 next_config_complete (void *nxdata
)
164 struct backend
*b
= nxdata
;
165 b
->config_complete (b
);
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)
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).
188 plugin_magic_config_key (struct backend
*b
)
190 return b
->next
->magic_config_key (b
->next
);
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
);
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
};
208 if (f
->filter
.open
) {
209 handle
= f
->filter
.open (next_open
, &nxdata
, readonly
);
212 backend_set_handle (b
, conn
, handle
);
215 if (backend_open (b
->next
, conn
, readonly
) == -1)
217 backend_set_handle (b
, conn
, NBDKIT_HANDLE_NOT_NEEDED
);
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’).
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
);
248 next_get_size (void *nxdata
)
250 struct b_conn
*b_conn
= nxdata
;
251 return backend_get_size (b_conn
->b
, b_conn
->conn
);
255 next_can_write (void *nxdata
)
257 struct b_conn
*b_conn
= nxdata
;
258 return backend_can_write (b_conn
->b
, b_conn
->conn
);
262 next_can_flush (void *nxdata
)
264 struct b_conn
*b_conn
= nxdata
;
265 return backend_can_flush (b_conn
->b
, b_conn
->conn
);
269 next_is_rotational (void *nxdata
)
271 struct b_conn
*b_conn
= nxdata
;
272 return backend_is_rotational (b_conn
->b
, b_conn
->conn
);
276 next_can_trim (void *nxdata
)
278 struct b_conn
*b_conn
= nxdata
;
279 return backend_can_trim (b_conn
->b
, b_conn
->conn
);
283 next_can_zero (void *nxdata
)
285 struct b_conn
*b_conn
= nxdata
;
286 return backend_can_zero (b_conn
->b
, b_conn
->conn
);
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
);
297 next_can_extents (void *nxdata
)
299 struct b_conn
*b_conn
= nxdata
;
300 return backend_can_extents (b_conn
->b
, b_conn
->conn
);
304 next_can_fua (void *nxdata
)
306 struct b_conn
*b_conn
= nxdata
;
307 return backend_can_fua (b_conn
->b
, b_conn
->conn
);
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
);
318 next_can_cache (void *nxdata
)
320 struct b_conn
*b_conn
= nxdata
;
321 return backend_can_cache (b_conn
->b
, b_conn
->conn
);
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
,
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
,
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
);
350 next_trim (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
353 struct b_conn
*b_conn
= nxdata
;
354 return backend_trim (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
358 next_zero (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
361 struct b_conn
*b_conn
= nxdata
;
362 return backend_zero (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
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
,
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
,
396 .pwrite
= next_pwrite
,
400 .extents
= next_extents
,
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
414 if (backend_prepare (b
->next
, conn
) == -1)
417 if (f
->filter
.prepare
&&
418 f
->filter
.prepare (&next_ops
, &nxdata
, handle
, readonly
) == -1)
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)
440 return b
->next
->finalize (b
->next
, conn
);
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
);
453 return backend_get_size (b
->next
, conn
);
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
);
466 return backend_can_write (b
->next
, conn
);
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
);
479 return backend_can_flush (b
->next
, conn
);
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
);
492 return backend_is_rotational (b
->next
, conn
);
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
);
505 return backend_can_trim (b
->next
, conn
);
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
);
518 return backend_can_zero (b
->next
, conn
);
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
);
531 return backend_can_fast_zero (b
->next
, conn
);
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
);
544 return backend_can_extents (b
->next
, conn
);
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
);
557 return backend_can_fua (b
->next
, conn
);
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
);
570 return backend_can_multi_conn (b
->next
, conn
);
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
);
583 return backend_can_cache (b
->next
, conn
);
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
};
596 return f
->filter
.pread (&next_ops
, &nxdata
, handle
,
597 buf
, count
, offset
, flags
, err
);
599 return backend_pread (b
->next
, conn
, buf
, count
, offset
, flags
, err
);
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
);
615 return backend_pwrite (b
->next
, conn
, buf
, count
, offset
, flags
, err
);
619 filter_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
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
};
627 return f
->filter
.flush (&next_ops
, &nxdata
, handle
, flags
, err
);
629 return backend_flush (b
->next
, conn
, flags
, err
);
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
};
642 return f
->filter
.trim (&next_ops
, &nxdata
, handle
, count
, offset
, flags
,
645 return backend_trim (b
->next
, conn
, count
, offset
, flags
, err
);
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
};
657 return f
->filter
.zero (&next_ops
, &nxdata
, handle
,
658 count
, offset
, flags
, err
);
660 return backend_zero (b
->next
, conn
, count
, offset
, flags
, err
);
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
,
677 return backend_extents (b
->next
, conn
, count
, offset
, flags
,
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
};
692 return f
->filter
.cache (&next_ops
, &nxdata
, handle
,
693 count
, offset
, flags
, err
);
695 return backend_cache (b
->next
, conn
, count
, offset
, flags
, err
);
698 static struct backend filter_functions
= {
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
,
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
,
728 .extents
= filter_extents
,
729 .cache
= filter_cache
,
732 /* Register and load a filter. */
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
);
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 ();
754 fprintf (stderr
, "%s: %s: filter registration function failed\n",
755 program_name
, filename
);
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
) {
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
);
771 if (filter
->_version
== NULL
||
772 strcmp (filter
->_version
, PACKAGE_VERSION
) != 0) {
774 "%s: %s: filter is incompatible with this version of nbdkit "
775 "(_version = %s, need %s)\n",
776 program_name
, filename
, filter
->_version
?: "<null>",
783 backend_load (&f
->backend
, f
->filter
.name
, f
->filter
.load
);
785 return (struct backend
*) f
;