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
46 /* We extend the generic backend struct with extra fields relating
49 struct backend_filter
{
50 struct backend backend
;
51 char *name
; /* copy of filter.name */
54 struct nbdkit_filter filter
;
57 /* Literally a backend + a connection pointer. This is the
58 * implementation of ‘void *nxdata’ in the filter API.
62 struct connection
*conn
;
65 /* Note this frees the whole chain. */
67 filter_free (struct backend
*b
)
69 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
71 f
->backend
.next
->free (f
->backend
.next
);
73 /* Acquiring this lock prevents any filter callbacks from running
78 debug ("%s: unload", f
->name
);
93 filter_thread_model (struct backend
*b
)
95 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
96 int filter_thread_model
= NBDKIT_THREAD_MODEL_PARALLEL
;
97 int thread_model
= f
->backend
.next
->thread_model (f
->backend
.next
);
99 if (f
->filter
.thread_model
) {
100 filter_thread_model
= f
->filter
.thread_model ();
101 if (filter_thread_model
== -1)
105 if (filter_thread_model
< thread_model
) /* more serialized */
106 thread_model
= filter_thread_model
;
111 /* This is actually passing the request through to the final plugin,
112 * hence the function name.
115 plugin_name (struct backend
*b
)
117 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
119 return f
->backend
.next
->plugin_name (f
->backend
.next
);
123 filter_name (struct backend
*b
)
125 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
131 filter_version (struct backend
*b
)
133 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
135 return f
->filter
.version
;
139 filter_usage (struct backend
*b
)
141 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
144 printf ("filter: %s", f
->name
);
145 if (f
->filter
.longname
)
146 printf (" (%s)", f
->filter
.longname
);
148 printf ("(%s)\n", f
->filename
);
149 if (f
->filter
.description
) {
150 printf ("%s", f
->filter
.description
);
151 if ((p
= strrchr (f
->filter
.description
, '\n')) == NULL
|| p
[1])
154 if (f
->filter
.config_help
) {
155 printf ("%s", f
->filter
.config_help
);
156 if ((p
= strrchr (f
->filter
.config_help
, '\n')) == NULL
|| p
[1])
162 filter_dump_fields (struct backend
*b
)
164 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
166 f
->backend
.next
->dump_fields (f
->backend
.next
);
170 next_config (void *nxdata
, const char *key
, const char *value
)
172 struct backend
*b
= nxdata
;
173 b
->config (b
, key
, value
);
178 filter_config (struct backend
*b
, const char *key
, const char *value
)
180 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
182 debug ("%s: config key=%s, value=%s",
183 f
->name
, key
, value
);
185 if (f
->filter
.config
) {
186 if (f
->filter
.config (next_config
, f
->backend
.next
, key
, value
) == -1)
190 f
->backend
.next
->config (f
->backend
.next
, key
, value
);
194 next_config_complete (void *nxdata
)
196 struct backend
*b
= nxdata
;
197 b
->config_complete (b
);
202 filter_config_complete (struct backend
*b
)
204 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
206 debug ("%s: config_complete", f
->name
);
208 if (f
->filter
.config_complete
) {
209 if (f
->filter
.config_complete (next_config_complete
, f
->backend
.next
) == -1)
213 f
->backend
.next
->config_complete (f
->backend
.next
);
216 /* magic_config_key only applies to plugins, so this passes the
217 * request through to the plugin (hence the name).
220 plugin_magic_config_key (struct backend
*b
)
222 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
224 return f
->backend
.next
->magic_config_key (f
->backend
.next
);
228 next_open (void *nxdata
, int readonly
)
230 struct b_conn
*b_conn
= nxdata
;
232 return b_conn
->b
->open (b_conn
->b
, b_conn
->conn
, readonly
);
236 filter_open (struct backend
*b
, struct connection
*conn
, int readonly
)
238 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
239 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
242 debug ("%s: open readonly=%d", f
->name
, readonly
);
244 if (f
->filter
.open
) {
245 handle
= f
->filter
.open (next_open
, &nxdata
, readonly
);
248 connection_set_handle (conn
, f
->backend
.i
, handle
);
252 return f
->backend
.next
->open (f
->backend
.next
, conn
, readonly
);
256 filter_close (struct backend
*b
, struct connection
*conn
)
258 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
259 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
261 debug ("%s: close", f
->name
);
264 f
->filter
.close (handle
);
265 f
->backend
.next
->close (f
->backend
.next
, conn
);
268 /* The next_functions structure contains pointers to backend
269 * functions. However because these functions are all expecting a
270 * backend and a connection, we cannot call them directly, but must
271 * write some next_* functions that unpack the two parameters from a
272 * single ‘void *nxdata’ struct pointer (‘b_conn’).
276 next_get_size (void *nxdata
)
278 struct b_conn
*b_conn
= nxdata
;
279 return b_conn
->b
->get_size (b_conn
->b
, b_conn
->conn
);
283 next_can_write (void *nxdata
)
285 struct b_conn
*b_conn
= nxdata
;
286 return b_conn
->b
->can_write (b_conn
->b
, b_conn
->conn
);
290 next_can_flush (void *nxdata
)
292 struct b_conn
*b_conn
= nxdata
;
293 return b_conn
->b
->can_flush (b_conn
->b
, b_conn
->conn
);
297 next_is_rotational (void *nxdata
)
299 struct b_conn
*b_conn
= nxdata
;
300 return b_conn
->b
->is_rotational (b_conn
->b
, b_conn
->conn
);
304 next_can_trim (void *nxdata
)
306 struct b_conn
*b_conn
= nxdata
;
307 return b_conn
->b
->can_trim (b_conn
->b
, b_conn
->conn
);
311 next_can_zero (void *nxdata
)
313 struct b_conn
*b_conn
= nxdata
;
314 return b_conn
->b
->can_zero (b_conn
->b
, b_conn
->conn
);
318 next_can_extents (void *nxdata
)
320 struct b_conn
*b_conn
= nxdata
;
321 return b_conn
->b
->can_extents (b_conn
->b
, b_conn
->conn
);
325 next_can_fua (void *nxdata
)
327 struct b_conn
*b_conn
= nxdata
;
328 return b_conn
->b
->can_fua (b_conn
->b
, b_conn
->conn
);
332 next_can_multi_conn (void *nxdata
)
334 struct b_conn
*b_conn
= nxdata
;
335 return b_conn
->b
->can_multi_conn (b_conn
->b
, b_conn
->conn
);
339 next_can_cache (void *nxdata
)
341 struct b_conn
*b_conn
= nxdata
;
342 return b_conn
->b
->can_cache (b_conn
->b
, b_conn
->conn
);
346 next_pread (void *nxdata
, void *buf
, uint32_t count
, uint64_t offset
,
347 uint32_t flags
, int *err
)
349 struct b_conn
*b_conn
= nxdata
;
350 return b_conn
->b
->pread (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
355 next_pwrite (void *nxdata
, const void *buf
, uint32_t count
, uint64_t offset
,
356 uint32_t flags
, int *err
)
358 struct b_conn
*b_conn
= nxdata
;
359 return b_conn
->b
->pwrite (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
364 next_flush (void *nxdata
, uint32_t flags
, int *err
)
366 struct b_conn
*b_conn
= nxdata
;
367 return b_conn
->b
->flush (b_conn
->b
, b_conn
->conn
, flags
, err
);
371 next_trim (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
374 struct b_conn
*b_conn
= nxdata
;
375 return b_conn
->b
->trim (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
379 next_zero (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
382 struct b_conn
*b_conn
= nxdata
;
383 return b_conn
->b
->zero (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
387 next_extents (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
388 struct nbdkit_extents
*extents
, int *err
)
390 struct b_conn
*b_conn
= nxdata
;
391 return b_conn
->b
->extents (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
,
396 next_cache (void *nxdata
, uint32_t count
, uint64_t offset
,
397 uint32_t flags
, int *err
)
399 struct b_conn
*b_conn
= nxdata
;
400 return b_conn
->b
->cache (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
,
404 static struct nbdkit_next_ops next_ops
= {
405 .get_size
= next_get_size
,
406 .can_write
= next_can_write
,
407 .can_flush
= next_can_flush
,
408 .is_rotational
= next_is_rotational
,
409 .can_trim
= next_can_trim
,
410 .can_zero
= next_can_zero
,
411 .can_extents
= next_can_extents
,
412 .can_fua
= next_can_fua
,
413 .can_multi_conn
= next_can_multi_conn
,
414 .can_cache
= next_can_cache
,
416 .pwrite
= next_pwrite
,
420 .extents
= next_extents
,
425 filter_prepare (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
, f
->backend
.i
);
429 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
431 debug ("%s: prepare", f
->name
);
433 /* Call these in order starting from the filter closest to the
436 if (f
->backend
.next
->prepare (f
->backend
.next
, conn
) == -1)
439 if (f
->filter
.prepare
&&
440 f
->filter
.prepare (&next_ops
, &nxdata
, handle
) == -1)
447 filter_finalize (struct backend
*b
, struct connection
*conn
)
449 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
450 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
451 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
453 debug ("%s: finalize", f
->name
);
455 /* Call these in reverse order to .prepare above, starting from the
456 * filter furthest away from the plugin.
458 if (f
->filter
.finalize
&&
459 f
->filter
.finalize (&next_ops
, &nxdata
, handle
) == -1)
462 return f
->backend
.next
->finalize (f
->backend
.next
, conn
);
466 filter_get_size (struct backend
*b
, struct connection
*conn
)
468 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
469 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
470 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
472 debug ("%s: get_size", f
->name
);
474 if (f
->filter
.get_size
)
475 return f
->filter
.get_size (&next_ops
, &nxdata
, handle
);
477 return f
->backend
.next
->get_size (f
->backend
.next
, conn
);
481 filter_can_write (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
, f
->backend
.i
);
485 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
487 debug ("%s: can_write", f
->name
);
489 if (f
->filter
.can_write
)
490 return f
->filter
.can_write (&next_ops
, &nxdata
, handle
);
492 return f
->backend
.next
->can_write (f
->backend
.next
, conn
);
496 filter_can_flush (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
, f
->backend
.i
);
500 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
502 debug ("%s: can_flush", f
->name
);
504 if (f
->filter
.can_flush
)
505 return f
->filter
.can_flush (&next_ops
, &nxdata
, handle
);
507 return f
->backend
.next
->can_flush (f
->backend
.next
, conn
);
511 filter_is_rotational (struct backend
*b
, struct connection
*conn
)
513 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
514 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
515 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
517 debug ("%s: is_rotational", f
->name
);
519 if (f
->filter
.is_rotational
)
520 return f
->filter
.is_rotational (&next_ops
, &nxdata
, handle
);
522 return f
->backend
.next
->is_rotational (f
->backend
.next
, conn
);
526 filter_can_trim (struct backend
*b
, struct connection
*conn
)
528 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
529 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
530 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
532 debug ("%s: can_trim", f
->name
);
534 if (f
->filter
.can_trim
)
535 return f
->filter
.can_trim (&next_ops
, &nxdata
, handle
);
537 return f
->backend
.next
->can_trim (f
->backend
.next
, conn
);
541 filter_can_zero (struct backend
*b
, struct connection
*conn
)
543 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
544 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
545 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
547 debug ("%s: can_zero", f
->name
);
549 if (f
->filter
.can_zero
)
550 return f
->filter
.can_zero (&next_ops
, &nxdata
, handle
);
552 return f
->backend
.next
->can_zero (f
->backend
.next
, conn
);
556 filter_can_extents (struct backend
*b
, struct connection
*conn
)
558 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
559 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
560 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
562 debug ("%s: can_extents", f
->name
);
564 if (f
->filter
.can_extents
)
565 return f
->filter
.can_extents (&next_ops
, &nxdata
, handle
);
567 return f
->backend
.next
->can_extents (f
->backend
.next
, conn
);
571 filter_can_fua (struct backend
*b
, struct connection
*conn
)
573 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
574 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
575 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
577 debug ("%s: can_fua", f
->name
);
579 if (f
->filter
.can_fua
)
580 return f
->filter
.can_fua (&next_ops
, &nxdata
, handle
);
582 return f
->backend
.next
->can_fua (f
->backend
.next
, conn
);
586 filter_can_multi_conn (struct backend
*b
, struct connection
*conn
)
588 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
589 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
590 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
592 debug ("%s: can_multi_conn", f
->name
);
594 if (f
->filter
.can_multi_conn
)
595 return f
->filter
.can_multi_conn (&next_ops
, &nxdata
, handle
);
597 return f
->backend
.next
->can_multi_conn (f
->backend
.next
, conn
);
601 filter_can_cache (struct backend
*b
, struct connection
*conn
)
603 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
604 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
605 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
607 debug ("%s: can_cache", f
->name
);
609 if (f
->filter
.can_cache
)
610 return f
->filter
.can_cache (&next_ops
, &nxdata
, handle
);
612 return f
->backend
.next
->can_cache (f
->backend
.next
, conn
);
616 filter_pread (struct backend
*b
, struct connection
*conn
,
617 void *buf
, uint32_t count
, uint64_t offset
,
618 uint32_t flags
, int *err
)
620 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
621 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
622 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
626 debug ("%s: pread count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
627 f
->name
, count
, offset
, flags
);
630 return f
->filter
.pread (&next_ops
, &nxdata
, handle
,
631 buf
, count
, offset
, flags
, err
);
633 return f
->backend
.next
->pread (f
->backend
.next
, conn
,
634 buf
, count
, offset
, flags
, err
);
638 filter_pwrite (struct backend
*b
, struct connection
*conn
,
639 const void *buf
, uint32_t count
, uint64_t offset
,
640 uint32_t flags
, int *err
)
642 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
643 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
644 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
646 assert (!(flags
& ~NBDKIT_FLAG_FUA
));
648 debug ("%s: pwrite count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
649 f
->name
, count
, offset
, flags
);
651 if (f
->filter
.pwrite
)
652 return f
->filter
.pwrite (&next_ops
, &nxdata
, handle
,
653 buf
, count
, offset
, flags
, err
);
655 return f
->backend
.next
->pwrite (f
->backend
.next
, conn
,
656 buf
, count
, offset
, flags
, err
);
660 filter_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
663 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
664 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
665 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
669 debug ("%s: flush flags=0x%" PRIx32
, f
->name
, flags
);
672 return f
->filter
.flush (&next_ops
, &nxdata
, handle
, flags
, err
);
674 return f
->backend
.next
->flush (f
->backend
.next
, conn
, flags
, err
);
678 filter_trim (struct backend
*b
, struct connection
*conn
,
679 uint32_t count
, uint64_t offset
,
680 uint32_t flags
, int *err
)
682 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
683 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
684 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
688 debug ("%s: trim count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
689 f
->name
, count
, offset
, flags
);
692 return f
->filter
.trim (&next_ops
, &nxdata
, handle
, count
, offset
, flags
,
695 return f
->backend
.next
->trim (f
->backend
.next
, conn
, count
, offset
, flags
,
700 filter_zero (struct backend
*b
, struct connection
*conn
,
701 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
703 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
704 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
705 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
707 assert (!(flags
& ~(NBDKIT_FLAG_MAY_TRIM
| NBDKIT_FLAG_FUA
)));
709 debug ("%s: zero count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
710 f
->name
, count
, offset
, flags
);
713 return f
->filter
.zero (&next_ops
, &nxdata
, handle
,
714 count
, offset
, flags
, err
);
716 return f
->backend
.next
->zero (f
->backend
.next
, conn
,
717 count
, offset
, flags
, err
);
721 filter_extents (struct backend
*b
, struct connection
*conn
,
722 uint32_t count
, uint64_t offset
, uint32_t flags
,
723 struct nbdkit_extents
*extents
, int *err
)
725 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
726 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
727 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
729 assert (!(flags
& ~NBDKIT_FLAG_REQ_ONE
));
731 debug ("%s: extents count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
732 f
->name
, count
, offset
, flags
);
734 if (f
->filter
.extents
)
735 return f
->filter
.extents (&next_ops
, &nxdata
, handle
,
736 count
, offset
, flags
,
739 return f
->backend
.next
->extents (f
->backend
.next
, conn
,
740 count
, offset
, flags
,
745 filter_cache (struct backend
*b
, struct connection
*conn
,
746 uint32_t count
, uint64_t offset
,
747 uint32_t flags
, int *err
)
749 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
750 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
751 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
755 debug ("%s: cache count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
756 f
->name
, count
, offset
, flags
);
759 return f
->filter
.cache (&next_ops
, &nxdata
, handle
,
760 count
, offset
, flags
, err
);
762 return f
->backend
.next
->cache (f
->backend
.next
, conn
,
763 count
, offset
, flags
, err
);
766 static struct backend filter_functions
= {
768 .thread_model
= filter_thread_model
,
770 .plugin_name
= plugin_name
,
771 .usage
= filter_usage
,
772 .version
= filter_version
,
773 .dump_fields
= filter_dump_fields
,
774 .config
= filter_config
,
775 .config_complete
= filter_config_complete
,
776 .magic_config_key
= plugin_magic_config_key
,
778 .prepare
= filter_prepare
,
779 .finalize
= filter_finalize
,
780 .close
= filter_close
,
781 .get_size
= filter_get_size
,
782 .can_write
= filter_can_write
,
783 .can_flush
= filter_can_flush
,
784 .is_rotational
= filter_is_rotational
,
785 .can_trim
= filter_can_trim
,
786 .can_zero
= filter_can_zero
,
787 .can_extents
= filter_can_extents
,
788 .can_fua
= filter_can_fua
,
789 .can_multi_conn
= filter_can_multi_conn
,
790 .can_cache
= filter_can_cache
,
791 .pread
= filter_pread
,
792 .pwrite
= filter_pwrite
,
793 .flush
= filter_flush
,
796 .extents
= filter_extents
,
797 .cache
= filter_cache
,
800 /* Register and load a filter. */
802 filter_register (struct backend
*next
, size_t index
, const char *filename
,
803 void *dl
, struct nbdkit_filter
*(*filter_init
) (void))
805 struct backend_filter
*f
;
806 const struct nbdkit_filter
*filter
;
809 f
= calloc (1, sizeof *f
);
816 f
->backend
= filter_functions
;
817 f
->backend
.next
= next
;
818 f
->backend
.i
= index
;
819 f
->filename
= strdup (filename
);
820 if (f
->filename
== NULL
) goto out_of_memory
;
823 debug ("registering filter %s", f
->filename
);
825 /* Call the initialization function which returns the address of the
826 * filter's own 'struct nbdkit_filter'.
828 filter
= filter_init ();
830 fprintf (stderr
, "%s: %s: filter registration function failed\n",
831 program_name
, f
->filename
);
835 /* We do not provide API or ABI guarantees for filters, other than
836 * the ABI position of _api_version that will let us diagnose
837 * mismatch when the API changes.
839 if (filter
->_api_version
!= NBDKIT_FILTER_API_VERSION
) {
841 "%s: %s: filter is incompatible with this version of nbdkit "
842 "(_api_version = %d)\n",
843 program_name
, f
->filename
, filter
->_api_version
);
849 /* Only filter.name is required. */
850 if (f
->filter
.name
== NULL
) {
851 fprintf (stderr
, "%s: %s: filter must have a .name field\n",
852 program_name
, f
->filename
);
856 len
= strlen (f
->filter
.name
);
858 fprintf (stderr
, "%s: %s: filter.name field must not be empty\n",
859 program_name
, f
->filename
);
862 for (i
= 0; i
< len
; ++i
) {
863 if (!((f
->filter
.name
[i
] >= '0' && f
->filter
.name
[i
] <= '9') ||
864 (f
->filter
.name
[i
] >= 'a' && f
->filter
.name
[i
] <= 'z') ||
865 (f
->filter
.name
[i
] >= 'A' && f
->filter
.name
[i
] <= 'Z'))) {
867 "%s: %s: filter.name ('%s') field "
868 "must contain only ASCII alphanumeric characters\n",
869 program_name
, f
->filename
, f
->filter
.name
);
874 /* Copy the module's name into local storage, so that filter.name
875 * survives past unload.
877 f
->name
= strdup (f
->filter
.name
);
878 if (f
->name
== NULL
) {
883 debug ("registered filter %s (name %s)", f
->filename
, f
->name
);
885 /* Set debug flags before calling load. */
886 set_debug_flags (dl
, f
->name
);
888 /* Call the on-load callback if it exists. */
889 debug ("%s: load", f
->name
);
893 return (struct backend
*) f
;