[Libguestfs] [PATCH nbdkit v4 11/15] truncate: Implement extents for beyond end of truncated region.

Richard W.M. Jones rjones at redhat.com
Tue Mar 26 21:17:20 UTC 2019


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

diff --git a/filters/truncate/truncate.c b/filters/truncate/truncate.c
index b95432a..11d32ff 100644
--- a/filters/truncate/truncate.c
+++ b/filters/truncate/truncate.c
@@ -285,6 +285,61 @@ 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)
+{
+  int r;
+  uint32_t n;
+  uint64_t real_size_copy;
+
+  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);
+  }
+
+  if (offset < real_size_copy) {
+    if (offset + count <= real_size_copy)
+      n = count;
+    else
+      n = real_size_copy - offset;
+    r = next_ops->extents (nxdata, n, offset, flags, extents, err);
+    if (r == -1)
+      return -1;
+    count -= n;
+  }
+
+  if (count > 0) {
+    size_t nr_extents = nbdkit_extents_count (extents);
+
+    /* If we are asked for extent information beyond the end of the
+     * real size of the underlying device, then we return a hole.
+     * However as we don't know if the underlying device returned the
+     * full extents data (it's not required to), check that we won't
+     * break the extents invariant first.
+     */
+    if (nr_extents > 0) {
+      struct nbdkit_extent e;
+
+      e = nbdkit_get_extent (extents, nr_extents-1);
+      if (e.offset + e.length == real_size_copy)
+        return nbdkit_add_extent (extents, real_size_copy, (uint64_t) count,
+                                  NBDKIT_EXTENT_ZERO|NBDKIT_EXTENT_HOLE);
+    }
+  }
+
+  return 0;
+}
+
 static struct nbdkit_filter filter = {
   .name              = "truncate",
   .longname          = "nbdkit truncate filter",
@@ -297,6 +352,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