[Libguestfs] [PATCH nbdkit v5 FINAL 12/19] truncate: Implement extents for beyond end of truncated region.

Richard W.M. Jones rjones at redhat.com
Thu Mar 28 16:18:39 UTC 2019


---
 filters/truncate/truncate.c | 55 +++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/filters/truncate/truncate.c b/filters/truncate/truncate.c
index b95432a..e8e56f7 100644
--- a/filters/truncate/truncate.c
+++ b/filters/truncate/truncate.c
@@ -285,6 +285,60 @@ truncate_zero (struct nbdkit_next_ops *next_ops, void *nxdata,
   return 0;
 }
 
+/* Extents. */
+static int
+truncate_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
+                  void *handle, uint32_t count, uint64_t offset,
+                  uint32_t flags, struct nbdkit_extents *extents, int *err)
+{
+  uint32_t n;
+  uint64_t real_size_copy;
+  struct nbdkit_extents *extents2;
+  size_t i;
+
+  pthread_mutex_lock (&lock);
+  real_size_copy = real_size;
+  pthread_mutex_unlock (&lock);
+
+  /* If the entire request is beyond the end of the underlying plugin
+   * then this is the easy case: return a hole.
+   */
+  if (offset >= real_size_copy)
+    return nbdkit_add_extent (extents, offset, (uint64_t) count,
+                              NBDKIT_EXTENT_ZERO|NBDKIT_EXTENT_HOLE);
+
+  /* We're asked first for extents information about the plugin, then
+   * possibly (if truncating larger) for the hole after the plugin.
+   * Since we're not required to provide all of this information, the
+   * easiest thing is to only return data from the plugin.  We will be
+   * called later about the hole.  However we do need to make sure
+   * that the extents array is truncated to the real size, hence we
+   * have to create a new extents array, ask the plugin, then copy the
+   * returned data to the original array.
+   */
+  extents2 = nbdkit_extents_new (0, real_size_copy);
+  if (offset + count <= real_size_copy)
+    n = count;
+  else
+    n = real_size_copy - offset;
+  if (next_ops->extents (nxdata, n, offset, flags, extents2, err) == -1) {
+    nbdkit_extents_free (extents2);
+    return -1;
+  }
+
+  for (i = 0; i < nbdkit_extents_count (extents2); ++i) {
+    struct nbdkit_extent e = nbdkit_get_extent (extents2, i);
+
+    if (nbdkit_add_extent (extents, e.offset, e.length, e.type) == -1) {
+      nbdkit_extents_free (extents2);
+      return -1;
+    }
+  }
+  nbdkit_extents_free (extents2);
+
+  return 0;
+}
+
 static struct nbdkit_filter filter = {
   .name              = "truncate",
   .longname          = "nbdkit truncate filter",
@@ -297,6 +351,7 @@ static struct nbdkit_filter filter = {
   .pwrite            = truncate_pwrite,
   .trim              = truncate_trim,
   .zero              = truncate_zero,
+  .extents           = truncate_extents,
 };
 
 NBDKIT_REGISTER_FILTER(filter)
-- 
2.20.1




More information about the Libguestfs mailing list