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

_______________________________________________
Libguestfs mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libguestfs

Reply via email to