Eric Blake
2019-Aug-28 16:38 UTC
[Libguestfs] [nbdkit PATCH] offset, partition: Fix .extents with non-zero offset
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@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
Richard W.M. Jones
2019-Aug-28 16:52 UTC
Re: [Libguestfs] [nbdkit PATCH] offset, partition: Fix .extents with non-zero offset
On Wed, Aug 28, 2019 at 11:38:15AM -0500, Eric Blake wrote:> 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@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; > --Yup, ACK. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top
Apparently Analagous Threads
- Re: [PATCH nbdkit v5 FINAL 10/19] offset: Implement mapping of extents.
- [nbdkit PATCH 0/4] Fix truncate handling of real_size
- Re: [PATCH nbdkit v5 FINAL 12/19] truncate: Implement extents for beyond end of truncated region.
- [PATCH nbdkit v5 FINAL 00/19] Implement extents.
- Re: [PATCH nbdkit 4/8] offset: Implement mapping of extents.