---
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