2 * Copyright (C) 2013-2018 Red Hat Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of Red Hat nor the names of its contributors may be
17 * used to endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 /* We extend the generic backend struct with extra fields relating
50 struct backend_filter
{
51 struct backend backend
;
52 char *name
; /* copy of filter.name */
55 struct nbdkit_filter filter
;
58 /* Literally a backend + a connection pointer. This is the
59 * implementation of ‘void *nxdata’ in the filter API.
63 struct connection
*conn
;
66 /* Note this frees the whole chain. */
68 filter_free (struct backend
*b
)
70 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
72 f
->backend
.next
->free (f
->backend
.next
);
74 /* Acquiring this lock prevents any filter callbacks from running
79 debug ("%s: unload", f
->filename
);
93 filter_thread_model (struct backend
*b
)
95 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
96 int filter_thread_model
= f
->filter
._thread_model
;
97 int thread_model
= f
->backend
.next
->thread_model (f
->backend
.next
);
99 if (filter_thread_model
< thread_model
) /* more serialized */
100 thread_model
= filter_thread_model
;
105 /* These are actually passing through to the final plugin, hence
106 * the function names.
109 plugin_name (struct backend
*b
)
111 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
113 return f
->backend
.next
->name (f
->backend
.next
);
117 filter_name (struct backend
*b
)
119 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
125 filter_version (struct backend
*b
)
127 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
129 return f
->filter
.version
;
133 filter_usage (struct backend
*b
)
135 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
137 printf ("filter: %s", f
->name
);
138 if (f
->filter
.longname
)
139 printf (" (%s)", f
->filter
.longname
);
141 printf ("(%s)", f
->filename
);
142 if (f
->filter
.description
) {
144 printf ("%s\n", f
->filter
.description
);
146 if (f
->filter
.config_help
) {
148 printf ("%s\n", f
->filter
.config_help
);
153 filter_dump_fields (struct backend
*b
)
155 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
157 f
->backend
.next
->dump_fields (f
->backend
.next
);
161 next_config (void *nxdata
, const char *key
, const char *value
)
163 struct backend
*b
= nxdata
;
164 b
->config (b
, key
, value
);
169 filter_config (struct backend
*b
, const char *key
, const char *value
)
171 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
173 debug ("%s: config key=%s, value=%s",
174 f
->filename
, key
, value
);
176 if (f
->filter
.config
) {
177 if (f
->filter
.config (next_config
, f
->backend
.next
, key
, value
) == -1)
181 f
->backend
.next
->config (f
->backend
.next
, key
, value
);
185 next_config_complete (void *nxdata
)
187 struct backend
*b
= nxdata
;
188 b
->config_complete (b
);
193 filter_config_complete (struct backend
*b
)
195 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
197 debug ("%s: config_complete", f
->filename
);
199 if (f
->filter
.config_complete
) {
200 if (f
->filter
.config_complete (next_config_complete
, f
->backend
.next
) == -1)
204 f
->backend
.next
->config_complete (f
->backend
.next
);
208 next_open (void *nxdata
, int readonly
)
210 struct b_conn
*b_conn
= nxdata
;
212 return b_conn
->b
->open (b_conn
->b
, b_conn
->conn
, readonly
);
216 filter_open (struct backend
*b
, struct connection
*conn
, int readonly
)
218 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
219 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
222 debug ("%s: open readonly=%d", f
->filename
, readonly
);
224 if (f
->filter
.open
) {
225 handle
= f
->filter
.open (next_open
, &nxdata
, readonly
);
228 connection_set_handle (conn
, f
->backend
.i
, handle
);
232 return f
->backend
.next
->open (f
->backend
.next
, conn
, readonly
);
236 filter_close (struct backend
*b
, struct connection
*conn
)
238 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
239 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
244 f
->filter
.close (handle
);
245 f
->backend
.next
->close (f
->backend
.next
, conn
);
248 /* The next_functions structure contains pointers to backend
249 * functions. However because these functions are all expecting a
250 * backend and a connection, we cannot call them directly, but must
251 * write some next_* functions that unpack the two parameters from a
252 * single ‘void *nxdata’ struct pointer (‘b_conn’).
256 next_get_size (void *nxdata
)
258 struct b_conn
*b_conn
= nxdata
;
259 return b_conn
->b
->get_size (b_conn
->b
, b_conn
->conn
);
263 next_can_write (void *nxdata
)
265 struct b_conn
*b_conn
= nxdata
;
266 return b_conn
->b
->can_write (b_conn
->b
, b_conn
->conn
);
270 next_can_flush (void *nxdata
)
272 struct b_conn
*b_conn
= nxdata
;
273 return b_conn
->b
->can_flush (b_conn
->b
, b_conn
->conn
);
277 next_is_rotational (void *nxdata
)
279 struct b_conn
*b_conn
= nxdata
;
280 return b_conn
->b
->is_rotational (b_conn
->b
, b_conn
->conn
);
284 next_can_trim (void *nxdata
)
286 struct b_conn
*b_conn
= nxdata
;
287 return b_conn
->b
->can_trim (b_conn
->b
, b_conn
->conn
);
291 next_pread (void *nxdata
, void *buf
, uint32_t count
, uint64_t offset
,
292 uint32_t flags
, int *err
)
294 struct b_conn
*b_conn
= nxdata
;
295 return b_conn
->b
->pread (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
300 next_pwrite (void *nxdata
, const void *buf
, uint32_t count
, uint64_t offset
,
301 uint32_t flags
, int *err
)
303 struct b_conn
*b_conn
= nxdata
;
304 return b_conn
->b
->pwrite (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
309 next_flush (void *nxdata
, uint32_t flags
, int *err
)
311 struct b_conn
*b_conn
= nxdata
;
312 return b_conn
->b
->flush (b_conn
->b
, b_conn
->conn
, flags
, err
);
316 next_trim (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
319 struct b_conn
*b_conn
= nxdata
;
320 return b_conn
->b
->trim (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
324 next_zero (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
327 struct b_conn
*b_conn
= nxdata
;
328 return b_conn
->b
->zero (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
331 static struct nbdkit_next_ops next_ops
= {
332 .get_size
= next_get_size
,
333 .can_write
= next_can_write
,
334 .can_flush
= next_can_flush
,
335 .is_rotational
= next_is_rotational
,
336 .can_trim
= next_can_trim
,
338 .pwrite
= next_pwrite
,
345 filter_prepare (struct backend
*b
, struct connection
*conn
)
347 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
348 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
349 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
353 if (f
->filter
.prepare
)
354 return f
->filter
.prepare (&next_ops
, &nxdata
, handle
);
356 return f
->backend
.next
->prepare (f
->backend
.next
, conn
);
360 filter_finalize (struct backend
*b
, struct connection
*conn
)
362 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
363 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
364 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
368 if (f
->filter
.finalize
)
369 return f
->filter
.finalize (&next_ops
, &nxdata
, handle
);
371 return f
->backend
.next
->finalize (f
->backend
.next
, conn
);
375 filter_get_size (struct backend
*b
, struct connection
*conn
)
377 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
378 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
379 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
383 if (f
->filter
.get_size
)
384 return f
->filter
.get_size (&next_ops
, &nxdata
, handle
);
386 return f
->backend
.next
->get_size (f
->backend
.next
, conn
);
390 filter_can_write (struct backend
*b
, struct connection
*conn
)
392 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
393 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
394 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
398 if (f
->filter
.can_write
)
399 return f
->filter
.can_write (&next_ops
, &nxdata
, handle
);
401 return f
->backend
.next
->can_write (f
->backend
.next
, conn
);
405 filter_can_flush (struct backend
*b
, struct connection
*conn
)
407 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
408 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
409 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
413 if (f
->filter
.can_flush
)
414 return f
->filter
.can_flush (&next_ops
, &nxdata
, handle
);
416 return f
->backend
.next
->can_flush (f
->backend
.next
, conn
);
420 filter_is_rotational (struct backend
*b
, struct connection
*conn
)
422 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
423 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
424 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
426 debug ("is_rotational");
428 if (f
->filter
.is_rotational
)
429 return f
->filter
.is_rotational (&next_ops
, &nxdata
, handle
);
431 return f
->backend
.next
->is_rotational (f
->backend
.next
, conn
);
435 filter_can_trim (struct backend
*b
, struct connection
*conn
)
437 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
438 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
439 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
443 if (f
->filter
.can_trim
)
444 return f
->filter
.can_trim (&next_ops
, &nxdata
, handle
);
446 return f
->backend
.next
->can_trim (f
->backend
.next
, conn
);
450 filter_pread (struct backend
*b
, struct connection
*conn
,
451 void *buf
, uint32_t count
, uint64_t offset
,
452 uint32_t flags
, int *err
)
454 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
455 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
456 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
460 debug ("pread count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
461 count
, offset
, flags
);
464 return f
->filter
.pread (&next_ops
, &nxdata
, handle
,
465 buf
, count
, offset
, flags
, err
);
467 return f
->backend
.next
->pread (f
->backend
.next
, conn
,
468 buf
, count
, offset
, flags
, err
);
472 filter_pwrite (struct backend
*b
, struct connection
*conn
,
473 const void *buf
, uint32_t count
, uint64_t offset
,
474 uint32_t flags
, int *err
)
476 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
477 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
478 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
480 assert (!(flags
& ~NBDKIT_FLAG_FUA
));
482 debug ("pwrite count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
483 count
, offset
, flags
);
485 if (f
->filter
.pwrite
)
486 return f
->filter
.pwrite (&next_ops
, &nxdata
, handle
,
487 buf
, count
, offset
, flags
, err
);
489 return f
->backend
.next
->pwrite (f
->backend
.next
, conn
,
490 buf
, count
, offset
, flags
, err
);
494 filter_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
497 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
498 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
499 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
503 debug ("flush flags=0x%" PRIx32
, flags
);
506 return f
->filter
.flush (&next_ops
, &nxdata
, handle
, flags
, err
);
508 return f
->backend
.next
->flush (f
->backend
.next
, conn
, flags
, err
);
512 filter_trim (struct backend
*b
, struct connection
*conn
,
513 uint32_t count
, uint64_t offset
,
514 uint32_t flags
, int *err
)
516 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
517 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
518 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
522 debug ("trim count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
523 count
, offset
, flags
);
526 return f
->filter
.trim (&next_ops
, &nxdata
, handle
, count
, offset
, flags
,
529 return f
->backend
.next
->trim (f
->backend
.next
, conn
, count
, offset
, flags
,
534 filter_zero (struct backend
*b
, struct connection
*conn
,
535 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
537 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
538 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
539 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
541 assert (!(flags
& ~(NBDKIT_FLAG_MAY_TRIM
| NBDKIT_FLAG_FUA
)));
543 debug ("zero count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
544 count
, offset
, flags
);
547 return f
->filter
.zero (&next_ops
, &nxdata
, handle
,
548 count
, offset
, flags
, err
);
550 return f
->backend
.next
->zero (f
->backend
.next
, conn
,
551 count
, offset
, flags
, err
);
554 static struct backend filter_functions
= {
556 .thread_model
= filter_thread_model
,
558 .plugin_name
= plugin_name
,
559 .usage
= filter_usage
,
560 .version
= filter_version
,
561 .dump_fields
= filter_dump_fields
,
562 .config
= filter_config
,
563 .config_complete
= filter_config_complete
,
565 .prepare
= filter_prepare
,
566 .finalize
= filter_finalize
,
567 .close
= filter_close
,
568 .get_size
= filter_get_size
,
569 .can_write
= filter_can_write
,
570 .can_flush
= filter_can_flush
,
571 .is_rotational
= filter_is_rotational
,
572 .can_trim
= filter_can_trim
,
573 .pread
= filter_pread
,
574 .pwrite
= filter_pwrite
,
575 .flush
= filter_flush
,
580 /* Register and load a filter. */
582 filter_register (struct backend
*next
, size_t index
, const char *filename
,
583 void *dl
, struct nbdkit_filter
*(*filter_init
) (void))
585 struct backend_filter
*f
;
586 const struct nbdkit_filter
*filter
;
589 f
= calloc (1, sizeof *f
);
596 f
->backend
= filter_functions
;
597 f
->backend
.next
= next
;
598 f
->backend
.i
= index
;
599 f
->filename
= strdup (filename
);
600 if (f
->filename
== NULL
) goto out_of_memory
;
603 debug ("registering filter %s", f
->filename
);
605 /* Call the initialization function which returns the address of the
606 * filter's own 'struct nbdkit_filter'.
608 filter
= filter_init ();
610 fprintf (stderr
, "%s: %s: filter registration function failed\n",
611 program_name
, f
->filename
);
615 /* We do not provide API or ABI guarantees for filters, other than
616 * the ABI position of _api_version that will let us diagnose
617 * mismatch when the API changes.
619 if (filter
->_api_version
!= NBDKIT_FILTER_API_VERSION
) {
620 fprintf (stderr
, "%s: %s: filter is incompatible with this version of nbdkit (_api_version = %d)\n",
621 program_name
, f
->filename
, filter
->_api_version
);
627 /* Only filter.name is required. */
628 if (f
->filter
.name
== NULL
) {
629 fprintf (stderr
, "%s: %s: filter must have a .name field\n",
630 program_name
, f
->filename
);
634 len
= strlen (f
->filter
.name
);
636 fprintf (stderr
, "%s: %s: filter.name field must not be empty\n",
637 program_name
, f
->filename
);
640 for (i
= 0; i
< len
; ++i
) {
641 if (!((f
->filter
.name
[i
] >= '0' && f
->filter
.name
[i
] <= '9') ||
642 (f
->filter
.name
[i
] >= 'a' && f
->filter
.name
[i
] <= 'z') ||
643 (f
->filter
.name
[i
] >= 'A' && f
->filter
.name
[i
] <= 'Z'))) {
644 fprintf (stderr
, "%s: %s: filter.name ('%s') field must contain only ASCII alphanumeric characters\n",
645 program_name
, f
->filename
, f
->filter
.name
);
650 /* Copy the module's name into local storage, so that filter.name
651 * survives past unload.
653 f
->name
= strdup (f
->filter
.name
);
654 if (f
->name
== NULL
) {
659 debug ("registered filter %s (name %s)", f
->filename
, f
->name
);
661 /* Call the on-load callback if it exists. */
662 debug ("%s: load", f
->filename
);
666 return (struct backend
*) f
;