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
);
216 return backend_open (b
->next
, conn
, readonly
);
220 filter_close (struct backend
*b
, struct connection
*conn
)
222 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
223 void *handle
= connection_get_handle (conn
, b
->i
);
225 debug ("%s: close", b
->name
);
228 f
->filter
.close (handle
);
229 b
->next
->close (b
->next
, conn
);
232 /* The next_functions structure contains pointers to backend
233 * functions. However because these functions are all expecting a
234 * backend and a connection, we cannot call them directly, but must
235 * write some next_* functions that unpack the two parameters from a
236 * single ‘void *nxdata’ struct pointer (‘b_conn’).
240 next_get_size (void *nxdata
)
242 struct b_conn
*b_conn
= nxdata
;
243 return backend_get_size (b_conn
->b
, b_conn
->conn
);
247 next_can_write (void *nxdata
)
249 struct b_conn
*b_conn
= nxdata
;
250 return backend_can_write (b_conn
->b
, b_conn
->conn
);
254 next_can_flush (void *nxdata
)
256 struct b_conn
*b_conn
= nxdata
;
257 return backend_can_flush (b_conn
->b
, b_conn
->conn
);
261 next_is_rotational (void *nxdata
)
263 struct b_conn
*b_conn
= nxdata
;
264 return backend_is_rotational (b_conn
->b
, b_conn
->conn
);
268 next_can_trim (void *nxdata
)
270 struct b_conn
*b_conn
= nxdata
;
271 return backend_can_trim (b_conn
->b
, b_conn
->conn
);
275 next_can_zero (void *nxdata
)
277 struct b_conn
*b_conn
= nxdata
;
278 return backend_can_zero (b_conn
->b
, b_conn
->conn
);
282 next_can_extents (void *nxdata
)
284 struct b_conn
*b_conn
= nxdata
;
285 return backend_can_extents (b_conn
->b
, b_conn
->conn
);
289 next_can_fua (void *nxdata
)
291 struct b_conn
*b_conn
= nxdata
;
292 return backend_can_fua (b_conn
->b
, b_conn
->conn
);
296 next_can_multi_conn (void *nxdata
)
298 struct b_conn
*b_conn
= nxdata
;
299 return backend_can_multi_conn (b_conn
->b
, b_conn
->conn
);
303 next_can_cache (void *nxdata
)
305 struct b_conn
*b_conn
= nxdata
;
306 return backend_can_cache (b_conn
->b
, b_conn
->conn
);
310 next_pread (void *nxdata
, void *buf
, uint32_t count
, uint64_t offset
,
311 uint32_t flags
, int *err
)
313 struct b_conn
*b_conn
= nxdata
;
314 return backend_pread (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
319 next_pwrite (void *nxdata
, const void *buf
, uint32_t count
, uint64_t offset
,
320 uint32_t flags
, int *err
)
322 struct b_conn
*b_conn
= nxdata
;
323 return backend_pwrite (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
328 next_flush (void *nxdata
, uint32_t flags
, int *err
)
330 struct b_conn
*b_conn
= nxdata
;
331 return backend_flush (b_conn
->b
, b_conn
->conn
, flags
, err
);
335 next_trim (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
338 struct b_conn
*b_conn
= nxdata
;
339 return backend_trim (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
343 next_zero (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
346 struct b_conn
*b_conn
= nxdata
;
347 return backend_zero (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
351 next_extents (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
352 struct nbdkit_extents
*extents
, int *err
)
354 struct b_conn
*b_conn
= nxdata
;
355 return backend_extents (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
,
360 next_cache (void *nxdata
, uint32_t count
, uint64_t offset
,
361 uint32_t flags
, int *err
)
363 struct b_conn
*b_conn
= nxdata
;
364 return backend_cache (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
367 static struct nbdkit_next_ops next_ops
= {
368 .get_size
= next_get_size
,
369 .can_write
= next_can_write
,
370 .can_flush
= next_can_flush
,
371 .is_rotational
= next_is_rotational
,
372 .can_trim
= next_can_trim
,
373 .can_zero
= next_can_zero
,
374 .can_extents
= next_can_extents
,
375 .can_fua
= next_can_fua
,
376 .can_multi_conn
= next_can_multi_conn
,
377 .can_cache
= next_can_cache
,
379 .pwrite
= next_pwrite
,
383 .extents
= next_extents
,
388 filter_prepare (struct backend
*b
, struct connection
*conn
)
390 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
391 void *handle
= connection_get_handle (conn
, b
->i
);
392 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
394 debug ("%s: prepare", b
->name
);
396 /* Call these in order starting from the filter closest to the
399 if (b
->next
->prepare (b
->next
, conn
) == -1)
402 if (f
->filter
.prepare
&&
403 f
->filter
.prepare (&next_ops
, &nxdata
, handle
) == -1)
410 filter_finalize (struct backend
*b
, struct connection
*conn
)
412 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
413 void *handle
= connection_get_handle (conn
, b
->i
);
414 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
416 debug ("%s: finalize", b
->name
);
418 /* Call these in reverse order to .prepare above, starting from the
419 * filter furthest away from the plugin.
421 if (f
->filter
.finalize
&&
422 f
->filter
.finalize (&next_ops
, &nxdata
, handle
) == -1)
425 return b
->next
->finalize (b
->next
, conn
);
429 filter_get_size (struct backend
*b
, struct connection
*conn
)
431 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
432 void *handle
= connection_get_handle (conn
, b
->i
);
433 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
435 if (f
->filter
.get_size
)
436 return f
->filter
.get_size (&next_ops
, &nxdata
, handle
);
438 return backend_get_size (b
->next
, conn
);
442 filter_can_write (struct backend
*b
, struct connection
*conn
)
444 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
445 void *handle
= connection_get_handle (conn
, b
->i
);
446 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
448 if (f
->filter
.can_write
)
449 return f
->filter
.can_write (&next_ops
, &nxdata
, handle
);
451 return backend_can_write (b
->next
, conn
);
455 filter_can_flush (struct backend
*b
, struct connection
*conn
)
457 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
458 void *handle
= connection_get_handle (conn
, b
->i
);
459 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
461 if (f
->filter
.can_flush
)
462 return f
->filter
.can_flush (&next_ops
, &nxdata
, handle
);
464 return backend_can_flush (b
->next
, conn
);
468 filter_is_rotational (struct backend
*b
, struct connection
*conn
)
470 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
471 void *handle
= connection_get_handle (conn
, b
->i
);
472 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
474 if (f
->filter
.is_rotational
)
475 return f
->filter
.is_rotational (&next_ops
, &nxdata
, handle
);
477 return backend_is_rotational (b
->next
, conn
);
481 filter_can_trim (struct backend
*b
, struct connection
*conn
)
483 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
484 void *handle
= connection_get_handle (conn
, b
->i
);
485 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
487 if (f
->filter
.can_trim
)
488 return f
->filter
.can_trim (&next_ops
, &nxdata
, handle
);
490 return backend_can_trim (b
->next
, conn
);
494 filter_can_zero (struct backend
*b
, struct connection
*conn
)
496 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
497 void *handle
= connection_get_handle (conn
, b
->i
);
498 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
500 if (f
->filter
.can_zero
)
501 return f
->filter
.can_zero (&next_ops
, &nxdata
, handle
);
503 return backend_can_zero (b
->next
, conn
);
507 filter_can_extents (struct backend
*b
, struct connection
*conn
)
509 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
510 void *handle
= connection_get_handle (conn
, b
->i
);
511 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
513 if (f
->filter
.can_extents
)
514 return f
->filter
.can_extents (&next_ops
, &nxdata
, handle
);
516 return backend_can_extents (b
->next
, conn
);
520 filter_can_fua (struct backend
*b
, struct connection
*conn
)
522 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
523 void *handle
= connection_get_handle (conn
, b
->i
);
524 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
526 if (f
->filter
.can_fua
)
527 return f
->filter
.can_fua (&next_ops
, &nxdata
, handle
);
529 return backend_can_fua (b
->next
, conn
);
533 filter_can_multi_conn (struct backend
*b
, struct connection
*conn
)
535 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
536 void *handle
= connection_get_handle (conn
, b
->i
);
537 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
539 if (f
->filter
.can_multi_conn
)
540 return f
->filter
.can_multi_conn (&next_ops
, &nxdata
, handle
);
542 return backend_can_multi_conn (b
->next
, conn
);
546 filter_can_cache (struct backend
*b
, struct connection
*conn
)
548 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
549 void *handle
= connection_get_handle (conn
, b
->i
);
550 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
552 if (f
->filter
.can_cache
)
553 return f
->filter
.can_cache (&next_ops
, &nxdata
, handle
);
555 return backend_can_cache (b
->next
, conn
);
559 filter_pread (struct backend
*b
, struct connection
*conn
,
560 void *buf
, uint32_t count
, uint64_t offset
,
561 uint32_t flags
, int *err
)
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
};
568 return f
->filter
.pread (&next_ops
, &nxdata
, handle
,
569 buf
, count
, offset
, flags
, err
);
571 return backend_pread (b
->next
, conn
, buf
, count
, offset
, flags
, err
);
575 filter_pwrite (struct backend
*b
, struct connection
*conn
,
576 const void *buf
, uint32_t count
, uint64_t offset
,
577 uint32_t flags
, int *err
)
579 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
580 void *handle
= connection_get_handle (conn
, b
->i
);
581 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
583 if (f
->filter
.pwrite
)
584 return f
->filter
.pwrite (&next_ops
, &nxdata
, handle
,
585 buf
, count
, offset
, flags
, err
);
587 return backend_pwrite (b
->next
, conn
, buf
, count
, offset
, flags
, err
);
591 filter_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
594 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
595 void *handle
= connection_get_handle (conn
, b
->i
);
596 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
599 return f
->filter
.flush (&next_ops
, &nxdata
, handle
, flags
, err
);
601 return backend_flush (b
->next
, conn
, flags
, err
);
605 filter_trim (struct backend
*b
, struct connection
*conn
,
606 uint32_t count
, uint64_t offset
,
607 uint32_t flags
, int *err
)
609 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
610 void *handle
= connection_get_handle (conn
, b
->i
);
611 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
614 return f
->filter
.trim (&next_ops
, &nxdata
, handle
, count
, offset
, flags
,
617 return backend_trim (b
->next
, conn
, count
, offset
, flags
, err
);
621 filter_zero (struct backend
*b
, struct connection
*conn
,
622 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
624 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
625 void *handle
= connection_get_handle (conn
, b
->i
);
626 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
629 return f
->filter
.zero (&next_ops
, &nxdata
, handle
,
630 count
, offset
, flags
, err
);
632 return backend_zero (b
->next
, conn
, count
, offset
, flags
, err
);
636 filter_extents (struct backend
*b
, struct connection
*conn
,
637 uint32_t count
, uint64_t offset
, uint32_t flags
,
638 struct nbdkit_extents
*extents
, int *err
)
640 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
641 void *handle
= connection_get_handle (conn
, b
->i
);
642 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
644 if (f
->filter
.extents
)
645 return f
->filter
.extents (&next_ops
, &nxdata
, handle
,
646 count
, offset
, flags
,
649 return backend_extents (b
->next
, conn
, count
, offset
, flags
,
654 filter_cache (struct backend
*b
, struct connection
*conn
,
655 uint32_t count
, uint64_t offset
,
656 uint32_t flags
, int *err
)
658 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
659 void *handle
= connection_get_handle (conn
, b
->i
);
660 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
664 return f
->filter
.cache (&next_ops
, &nxdata
, handle
,
665 count
, offset
, flags
, err
);
667 return backend_cache (b
->next
, conn
, count
, offset
, flags
, err
);
670 static struct backend filter_functions
= {
672 .thread_model
= filter_thread_model
,
673 .plugin_name
= plugin_name
,
674 .usage
= filter_usage
,
675 .version
= filter_version
,
676 .dump_fields
= filter_dump_fields
,
677 .config
= filter_config
,
678 .config_complete
= filter_config_complete
,
679 .magic_config_key
= plugin_magic_config_key
,
681 .prepare
= filter_prepare
,
682 .finalize
= filter_finalize
,
683 .close
= filter_close
,
684 .get_size
= filter_get_size
,
685 .can_write
= filter_can_write
,
686 .can_flush
= filter_can_flush
,
687 .is_rotational
= filter_is_rotational
,
688 .can_trim
= filter_can_trim
,
689 .can_zero
= filter_can_zero
,
690 .can_extents
= filter_can_extents
,
691 .can_fua
= filter_can_fua
,
692 .can_multi_conn
= filter_can_multi_conn
,
693 .can_cache
= filter_can_cache
,
694 .pread
= filter_pread
,
695 .pwrite
= filter_pwrite
,
696 .flush
= filter_flush
,
699 .extents
= filter_extents
,
700 .cache
= filter_cache
,
703 /* Register and load a filter. */
705 filter_register (struct backend
*next
, size_t index
, const char *filename
,
706 void *dl
, struct nbdkit_filter
*(*filter_init
) (void))
708 struct backend_filter
*f
;
709 const struct nbdkit_filter
*filter
;
711 f
= calloc (1, sizeof *f
);
717 f
->backend
= filter_functions
;
718 backend_init (&f
->backend
, next
, index
, filename
, dl
, "filter");
720 /* Call the initialization function which returns the address of the
721 * filter's own 'struct nbdkit_filter'.
723 filter
= filter_init ();
725 fprintf (stderr
, "%s: %s: filter registration function failed\n",
726 program_name
, filename
);
730 /* We do not provide API or ABI guarantees for filters, other than
731 * the ABI position and API contents of _api_version and _version to
732 * diagnose mismatch from the current nbdkit version.
734 if (filter
->_api_version
!= NBDKIT_FILTER_API_VERSION
) {
736 "%s: %s: filter is incompatible with this version of nbdkit "
737 "(_api_version = %d, need %d)\n",
738 program_name
, filename
, filter
->_api_version
,
739 NBDKIT_FILTER_API_VERSION
);
742 if (filter
->_version
== NULL
||
743 strcmp (filter
->_version
, PACKAGE_VERSION
) != 0) {
745 "%s: %s: filter is incompatible with this version of nbdkit "
746 "(_version = %s, need %s)\n",
747 program_name
, filename
, filter
->_version
?: "<null>",
754 backend_load (&f
->backend
, f
->filter
.name
, f
->filter
.load
);
756 return (struct backend
*) f
;