On 07/31/2018 02:55 PM, Richard W.M. Jones wrote:
This can truncate, extend, or round up/down to a multiple.
---
common-rules.mk | 3 +-
configure.ac | 1 +
filters/offset/nbdkit-offset-filter.pod | 7 +-
filters/partition/nbdkit-partition-filter.pod | 1 +
filters/truncate/Makefile.am | 60 ++++
filters/truncate/nbdkit-truncate-filter.pod | 87 ++++++
filters/truncate/truncate.c | 261 ++++++++++++++++++
7 files changed, 417 insertions(+), 3 deletions(-)
+/* Get the size. As a side effect, calculate the size to serve. */
+static int64_t
+truncate_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
+ void *handle)
+{
+ real_size = size = next_ops->get_size (nxdata);
+
+ /* The truncate, round-up and round-down parameters are treated as
+ * separate operations. It's possible to specify more than one,
+ * although perhaps not very useful.
+ */
+ if (truncate >= 0)
+ size = truncate;
+ if (round_up > 0)
+ size = (size + round_up - 1) & ~(round_up-1);
+ if (round_down > 0)
+ size &= ~(round_down-1);
These last two operations presuppose that the user passed in a power of
2, but nothing actually enforces that the user did that. Something like
'round-up=5 round-down=3' thus produces strange results; I'd require
powers of 2 to not have to worry about it elsewhere.
+/* Return true iff the buffer is all zero bytes.
+ *
+ * The clever approach here was suggested by Eric Blake. See:
+ *
https://www.redhat.com/archives/libguestfs/2017-April/msg00171.html
+ */
+static inline int
Worth using bool (via <stdbool.h>) here...
+is_zero (const char *buffer, size_t size)
+{
+ size_t i;
+ const size_t limit = size < 16 ? size : 16;
+
+ for (i = 0; i < limit; ++i)
+ if (buffer[i])
+ return 0;
...and actually returning false/true, to match the documentation?
Otherwise looks good to me. The offset filter duplicates behavior when
real_size > truncated size, but the real win with this filter is when
real_size < truncated size for quickly padding a plugin's actual length
into a more practical length (qemu already does just that on every
single image, rounding out to sector boundaries, although when it comes
to writing in the last partial sector, qemu actually tries to resize the
underlying file, for slightly less predictable outcomes than your nice
trick of EIO unless the action doesn't change the all-zero read nature
of the tail).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization:
qemu.org |
libvirt.org