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(a)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