[Libguestfs] [nbdkit PATCH] offset, partition: Fix .extents with non-zero offset

Eric Blake eblake at redhat.com
Wed Aug 28 16:38:15 UTC 2019


When querying the extents of the underlying plugin, we should only
translate the starting offset, and let the plugin report for at least
as many bytes as our range permits.  Otherwise, short-changing the
range causes bad behavior such as returning 0 extents, or even failing
the creation of an extents tracker:

$ cat script
case "$1" in
    get_size) echo 1m;;
    can_extents) ;;
    extents) echo 0 1m;;
    *) exit 2 ;;
esac
$ nbdkit -U - --filter=offset sh script offset=64k \
  --run 'qemu-io -r -f raw -c map $nbd'
nbdkit: sh[1]: error: extents: plugin must return at least one extent
896 KiB (0xe0000) bytes     allocated at offset 0 bytes (0x0)
nbdkit: sh[1]: error: extents: plugin must return at least one extent
qemu-io: Failed to get allocation status: Invalid argument
$ nbdkit -U - --filter=offset sh script offset=640k \
  --run 'qemu-io -r -f raw -c map $nbd'
nbdkit: sh[1]: error: nbdkit_extents_new: start (655360) >= end (393216)
qemu-io: Failed to get allocation status: Invalid argument

Fixes: 1a5e2d9c, 624abb36
Signed-off-by: Eric Blake <eblake at redhat.com>
---

At least we're catching this now before 1.14.

 docs/nbdkit-filter.pod        | 2 +-
 filters/offset/offset.c       | 4 ++--
 filters/partition/partition.c | 3 +--
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/docs/nbdkit-filter.pod b/docs/nbdkit-filter.pod
index 6e2bea61..cfd664eb 100644
--- a/docs/nbdkit-filter.pod
+++ b/docs/nbdkit-filter.pod
@@ -560,7 +560,7 @@ from the layer below.  Without error checking it would look like this:
    int64_t size;

    size = next_ops->get_size (nxdata);
-   extents2 = nbdkit_extents_new (offset + shift, size - shift);
+   extents2 = nbdkit_extents_new (offset + shift, size);
    next_ops->extents (nxdata, count, offset + shift, flags, extents2, err);
    for (i = 0; i < nbdkit_extents_count (extents2); ++i) {
      e = nbdkit_get_extent (extents2, i);
diff --git a/filters/offset/offset.c b/filters/offset/offset.c
index efe5c6d1..00122770 100644
--- a/filters/offset/offset.c
+++ b/filters/offset/offset.c
@@ -140,9 +140,9 @@ offset_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
   size_t i;
   CLEANUP_EXTENTS_FREE struct nbdkit_extents *extents2 = NULL;
   struct nbdkit_extent e;
-  int64_t real_size = next_ops->get_size (nxdata);
+  int64_t real_size = range >= 0 ? offset + range : next_ops->get_size (nxdata);

-  extents2 = nbdkit_extents_new (offs + offset, real_size - offset);
+  extents2 = nbdkit_extents_new (offs + offset, real_size);
   if (extents2 == NULL) {
     *err = errno;
     return -1;
diff --git a/filters/partition/partition.c b/filters/partition/partition.c
index 56ad05e2..b1b1945d 100644
--- a/filters/partition/partition.c
+++ b/filters/partition/partition.c
@@ -230,9 +230,8 @@ partition_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
   size_t i;
   CLEANUP_EXTENTS_FREE struct nbdkit_extents *extents2 = NULL;
   struct nbdkit_extent e;
-  int64_t real_size = next_ops->get_size (nxdata);

-  extents2 = nbdkit_extents_new (offs + h->offset, real_size - h->offset);
+  extents2 = nbdkit_extents_new (offs + h->offset, h->offset + h->range);
   if (extents2 == NULL) {
     *err = errno;
     return -1;
-- 
2.21.0




More information about the Libguestfs mailing list