On 3/20/19 5:11 PM, Richard W.M. Jones wrote:
This uses a new API VixDiskLib_QueryAllocatedBlocks provided in
VDDK >= 6.7.
Thanks: Martin Kletzander.
---
plugins/vddk/vddk-structs.h | 15 +++-
plugins/vddk/vddk.c | 138 ++++++++++++++++++++++++++++++++++++
2 files changed, 152 insertions(+), 1 deletion(-)
+static int
+vddk_extents (void *handle, uint32_t count, uint64_t offset, uint32_t flags,
+ struct nbdkit_extents *extents)
+{
+ struct vddk_handle *h = handle;
+ bool req_one = flags & NBDKIT_FLAG_REQ_ONE;
+ uint64_t position, end, start_sector;
+
+ position = offset;
+
...
+
+ for (i = 0; i < block_list->numBlocks; ++i) {
+ uint64_t offset, length;
+
+ offset = block_list->blocks[i].offset * VIXDISKLIB_SECTOR_SIZE;
+ length = block_list->blocks[i].length * VIXDISKLIB_SECTOR_SIZE;
+
+ /* The query returns blocks. We must insert holes between the
+ * blocks as necessary.
+ */
+ if (position < offset) {
+ if (nbdkit_add_extent (extents,
+ offset, length,
+ NBDKIT_EXTENT_HOLE | NBDKIT_EXTENT_ZERO) == -1)
+ goto error_in_add;
+ }
+
+ if (nbdkit_add_extent (extents,
+ offset, length, 0 /* allocated data */) == -1) {
+ error_in_add:
+ DEBUG_CALL ("VixDiskLib_FreeBlockList", "block_list");
+ VixDiskLib_FreeBlockList (block_list);
+ return -1;
+ }
+
+ position = offset + length;
This inner loop might be long; you could add this:
if (req_one)
break;
+ }
+ DEBUG_CALL ("VixDiskLib_FreeBlockList", "block_list");
+ VixDiskLib_FreeBlockList (block_list);
+
+ start_sector += nr_sectors;
+
+ if (req_one)
+ break;
just as you break the outer loop here, to make REQ_ONE slightly faster.
Otherwise looks sane. m not in a position to test it, but if 'qemu-img
map --output=json nbd://...' pointing to your server matches what you
expect for vddk, that's a good sign.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org