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
};
207 /* Most filters will call next_open first, resulting in
208 * inner-to-outer ordering.
211 return f
->filter
.open (next_open
, &nxdata
, readonly
);
212 else if (backend_open (b
->next
, conn
, readonly
) == -1)
215 return NBDKIT_HANDLE_NOT_NEEDED
;
219 filter_close (struct backend
*b
, struct connection
*conn
, void *handle
)
221 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
223 if (handle
&& f
->filter
.close
)
224 f
->filter
.close (handle
);
227 /* The next_functions structure contains pointers to backend
228 * functions. However because these functions are all expecting a
229 * backend and a connection, we cannot call them directly, but must
230 * write some next_* functions that unpack the two parameters from a
231 * single ‘void *nxdata’ struct pointer (‘b_conn’).
235 next_reopen (void *nxdata
, int readonly
)
237 struct b_conn
*b_conn
= nxdata
;
238 return backend_reopen (b_conn
->b
, b_conn
->conn
, readonly
);
242 next_get_size (void *nxdata
)
244 struct b_conn
*b_conn
= nxdata
;
245 return backend_get_size (b_conn
->b
, b_conn
->conn
);
249 next_can_write (void *nxdata
)
251 struct b_conn
*b_conn
= nxdata
;
252 return backend_can_write (b_conn
->b
, b_conn
->conn
);
256 next_can_flush (void *nxdata
)
258 struct b_conn
*b_conn
= nxdata
;
259 return backend_can_flush (b_conn
->b
, b_conn
->conn
);
263 next_is_rotational (void *nxdata
)
265 struct b_conn
*b_conn
= nxdata
;
266 return backend_is_rotational (b_conn
->b
, b_conn
->conn
);
270 next_can_trim (void *nxdata
)
272 struct b_conn
*b_conn
= nxdata
;
273 return backend_can_trim (b_conn
->b
, b_conn
->conn
);
277 next_can_zero (void *nxdata
)
279 struct b_conn
*b_conn
= nxdata
;
280 return backend_can_zero (b_conn
->b
, b_conn
->conn
);
284 next_can_fast_zero (void *nxdata
)
286 struct b_conn
*b_conn
= nxdata
;
287 return backend_can_fast_zero (b_conn
->b
, b_conn
->conn
);
291 next_can_extents (void *nxdata
)
293 struct b_conn
*b_conn
= nxdata
;
294 return backend_can_extents (b_conn
->b
, b_conn
->conn
);
298 next_can_fua (void *nxdata
)
300 struct b_conn
*b_conn
= nxdata
;
301 return backend_can_fua (b_conn
->b
, b_conn
->conn
);
305 next_can_multi_conn (void *nxdata
)
307 struct b_conn
*b_conn
= nxdata
;
308 return backend_can_multi_conn (b_conn
->b
, b_conn
->conn
);
312 next_can_cache (void *nxdata
)
314 struct b_conn
*b_conn
= nxdata
;
315 return backend_can_cache (b_conn
->b
, b_conn
->conn
);
319 next_pread (void *nxdata
, void *buf
, uint32_t count
, uint64_t offset
,
320 uint32_t flags
, int *err
)
322 struct b_conn
*b_conn
= nxdata
;
323 return backend_pread (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
328 next_pwrite (void *nxdata
, const void *buf
, uint32_t count
, uint64_t offset
,
329 uint32_t flags
, int *err
)
331 struct b_conn
*b_conn
= nxdata
;
332 return backend_pwrite (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
337 next_flush (void *nxdata
, uint32_t flags
, int *err
)
339 struct b_conn
*b_conn
= nxdata
;
340 return backend_flush (b_conn
->b
, b_conn
->conn
, flags
, err
);
344 next_trim (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
347 struct b_conn
*b_conn
= nxdata
;
348 return backend_trim (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
352 next_zero (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
355 struct b_conn
*b_conn
= nxdata
;
356 return backend_zero (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
360 next_extents (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
361 struct nbdkit_extents
*extents
, int *err
)
363 struct b_conn
*b_conn
= nxdata
;
364 return backend_extents (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
,
369 next_cache (void *nxdata
, uint32_t count
, uint64_t offset
,
370 uint32_t flags
, int *err
)
372 struct b_conn
*b_conn
= nxdata
;
373 return backend_cache (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
376 static struct nbdkit_next_ops next_ops
= {
377 .reopen
= next_reopen
,
378 .get_size
= next_get_size
,
379 .can_write
= next_can_write
,
380 .can_flush
= next_can_flush
,
381 .is_rotational
= next_is_rotational
,
382 .can_trim
= next_can_trim
,
383 .can_zero
= next_can_zero
,
384 .can_fast_zero
= next_can_fast_zero
,
385 .can_extents
= next_can_extents
,
386 .can_fua
= next_can_fua
,
387 .can_multi_conn
= next_can_multi_conn
,
388 .can_cache
= next_can_cache
,
390 .pwrite
= next_pwrite
,
394 .extents
= next_extents
,
399 filter_prepare (struct backend
*b
, struct connection
*conn
, void *handle
,
402 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
403 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
405 if (f
->filter
.prepare
&&
406 f
->filter
.prepare (&next_ops
, &nxdata
, handle
, readonly
) == -1)
413 filter_finalize (struct backend
*b
, struct connection
*conn
, void *handle
)
415 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
416 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
418 if (f
->filter
.finalize
&&
419 f
->filter
.finalize (&next_ops
, &nxdata
, handle
) == -1)
425 filter_get_size (struct backend
*b
, struct connection
*conn
, void *handle
)
427 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
428 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
430 if (f
->filter
.get_size
)
431 return f
->filter
.get_size (&next_ops
, &nxdata
, handle
);
433 return backend_get_size (b
->next
, conn
);
437 filter_can_write (struct backend
*b
, struct connection
*conn
, void *handle
)
439 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
440 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
442 if (f
->filter
.can_write
)
443 return f
->filter
.can_write (&next_ops
, &nxdata
, handle
);
445 return backend_can_write (b
->next
, conn
);
449 filter_can_flush (struct backend
*b
, struct connection
*conn
, void *handle
)
451 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
452 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
454 if (f
->filter
.can_flush
)
455 return f
->filter
.can_flush (&next_ops
, &nxdata
, handle
);
457 return backend_can_flush (b
->next
, conn
);
461 filter_is_rotational (struct backend
*b
, struct connection
*conn
, void *handle
)
463 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
464 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
466 if (f
->filter
.is_rotational
)
467 return f
->filter
.is_rotational (&next_ops
, &nxdata
, handle
);
469 return backend_is_rotational (b
->next
, conn
);
473 filter_can_trim (struct backend
*b
, struct connection
*conn
, void *handle
)
475 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
476 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
478 if (f
->filter
.can_trim
)
479 return f
->filter
.can_trim (&next_ops
, &nxdata
, handle
);
481 return backend_can_trim (b
->next
, conn
);
485 filter_can_zero (struct backend
*b
, struct connection
*conn
, void *handle
)
487 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
488 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
490 if (f
->filter
.can_zero
)
491 return f
->filter
.can_zero (&next_ops
, &nxdata
, handle
);
493 return backend_can_zero (b
->next
, conn
);
497 filter_can_fast_zero (struct backend
*b
, struct connection
*conn
, void *handle
)
499 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
500 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
502 if (f
->filter
.can_fast_zero
)
503 return f
->filter
.can_fast_zero (&next_ops
, &nxdata
, handle
);
505 return backend_can_fast_zero (b
->next
, conn
);
509 filter_can_extents (struct backend
*b
, struct connection
*conn
, void *handle
)
511 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
512 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
514 if (f
->filter
.can_extents
)
515 return f
->filter
.can_extents (&next_ops
, &nxdata
, handle
);
517 return backend_can_extents (b
->next
, conn
);
521 filter_can_fua (struct backend
*b
, struct connection
*conn
, void *handle
)
523 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
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
, void *handle
)
535 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
536 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
538 if (f
->filter
.can_multi_conn
)
539 return f
->filter
.can_multi_conn (&next_ops
, &nxdata
, handle
);
541 return backend_can_multi_conn (b
->next
, conn
);
545 filter_can_cache (struct backend
*b
, struct connection
*conn
, void *handle
)
547 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
548 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
550 if (f
->filter
.can_cache
)
551 return f
->filter
.can_cache (&next_ops
, &nxdata
, handle
);
553 return backend_can_cache (b
->next
, conn
);
557 filter_pread (struct backend
*b
, struct connection
*conn
, void *handle
,
558 void *buf
, uint32_t count
, uint64_t offset
,
559 uint32_t flags
, int *err
)
561 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
562 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
565 return f
->filter
.pread (&next_ops
, &nxdata
, handle
,
566 buf
, count
, offset
, flags
, err
);
568 return backend_pread (b
->next
, conn
, buf
, count
, offset
, flags
, err
);
572 filter_pwrite (struct backend
*b
, struct connection
*conn
, void *handle
,
573 const void *buf
, uint32_t count
, uint64_t offset
,
574 uint32_t flags
, int *err
)
576 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
577 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
579 if (f
->filter
.pwrite
)
580 return f
->filter
.pwrite (&next_ops
, &nxdata
, handle
,
581 buf
, count
, offset
, flags
, err
);
583 return backend_pwrite (b
->next
, conn
, buf
, count
, offset
, flags
, err
);
587 filter_flush (struct backend
*b
, struct connection
*conn
, void *handle
,
588 uint32_t flags
, int *err
)
590 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
591 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
594 return f
->filter
.flush (&next_ops
, &nxdata
, handle
, flags
, err
);
596 return backend_flush (b
->next
, conn
, flags
, err
);
600 filter_trim (struct backend
*b
, struct connection
*conn
, void *handle
,
601 uint32_t count
, uint64_t offset
,
602 uint32_t flags
, int *err
)
604 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
605 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
608 return f
->filter
.trim (&next_ops
, &nxdata
, handle
, count
, offset
, flags
,
611 return backend_trim (b
->next
, conn
, count
, offset
, flags
, err
);
615 filter_zero (struct backend
*b
, struct connection
*conn
, void *handle
,
616 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
618 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
619 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
622 return f
->filter
.zero (&next_ops
, &nxdata
, handle
,
623 count
, offset
, flags
, err
);
625 return backend_zero (b
->next
, conn
, count
, offset
, flags
, err
);
629 filter_extents (struct backend
*b
, struct connection
*conn
, void *handle
,
630 uint32_t count
, uint64_t offset
, uint32_t flags
,
631 struct nbdkit_extents
*extents
, int *err
)
633 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
634 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
636 if (f
->filter
.extents
)
637 return f
->filter
.extents (&next_ops
, &nxdata
, handle
,
638 count
, offset
, flags
,
641 return backend_extents (b
->next
, conn
, count
, offset
, flags
,
646 filter_cache (struct backend
*b
, struct connection
*conn
, void *handle
,
647 uint32_t count
, uint64_t offset
,
648 uint32_t flags
, int *err
)
650 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
651 struct b_conn nxdata
= { .b
= b
->next
, .conn
= conn
};
655 return f
->filter
.cache (&next_ops
, &nxdata
, handle
,
656 count
, offset
, flags
, err
);
658 return backend_cache (b
->next
, conn
, count
, offset
, flags
, err
);
661 static struct backend filter_functions
= {
663 .thread_model
= filter_thread_model
,
664 .plugin_name
= plugin_name
,
665 .usage
= filter_usage
,
666 .version
= filter_version
,
667 .dump_fields
= filter_dump_fields
,
668 .config
= filter_config
,
669 .config_complete
= filter_config_complete
,
670 .magic_config_key
= plugin_magic_config_key
,
672 .prepare
= filter_prepare
,
673 .finalize
= filter_finalize
,
674 .close
= filter_close
,
675 .get_size
= filter_get_size
,
676 .can_write
= filter_can_write
,
677 .can_flush
= filter_can_flush
,
678 .is_rotational
= filter_is_rotational
,
679 .can_trim
= filter_can_trim
,
680 .can_zero
= filter_can_zero
,
681 .can_fast_zero
= filter_can_fast_zero
,
682 .can_extents
= filter_can_extents
,
683 .can_fua
= filter_can_fua
,
684 .can_multi_conn
= filter_can_multi_conn
,
685 .can_cache
= filter_can_cache
,
686 .pread
= filter_pread
,
687 .pwrite
= filter_pwrite
,
688 .flush
= filter_flush
,
691 .extents
= filter_extents
,
692 .cache
= filter_cache
,
695 /* Register and load a filter. */
697 filter_register (struct backend
*next
, size_t index
, const char *filename
,
698 void *dl
, struct nbdkit_filter
*(*filter_init
) (void))
700 struct backend_filter
*f
;
701 const struct nbdkit_filter
*filter
;
703 f
= calloc (1, sizeof *f
);
709 f
->backend
= filter_functions
;
710 backend_init (&f
->backend
, next
, index
, filename
, dl
, "filter");
712 /* Call the initialization function which returns the address of the
713 * filter's own 'struct nbdkit_filter'.
715 filter
= filter_init ();
717 fprintf (stderr
, "%s: %s: filter registration function failed\n",
718 program_name
, filename
);
722 /* We do not provide API or ABI guarantees for filters, other than
723 * the ABI position and API contents of _api_version and _version to
724 * diagnose mismatch from the current nbdkit version.
726 if (filter
->_api_version
!= NBDKIT_FILTER_API_VERSION
) {
728 "%s: %s: filter is incompatible with this version of nbdkit "
729 "(_api_version = %d, need %d)\n",
730 program_name
, filename
, filter
->_api_version
,
731 NBDKIT_FILTER_API_VERSION
);
734 if (filter
->_version
== NULL
||
735 strcmp (filter
->_version
, PACKAGE_VERSION
) != 0) {
737 "%s: %s: filter is incompatible with this version of nbdkit "
738 "(_version = %s, need %s)\n",
739 program_name
, filename
, filter
->_version
?: "<null>",
746 backend_load (&f
->backend
, f
->filter
.name
, f
->filter
.load
);
748 return (struct backend
*) f
;