On 06/20/2018 10:43 AM, Eric Blake wrote:
On 06/20/2018 06:24 AM, Eric Blake wrote:
+/* Set several extents, describing region of given @length with
given @flags.
+ * Do not set more than @nb_extents, return number of set extents.
+ */
+static unsigned add_extents(NBDExtent *extents, unsigned nb_extents,
+ uint64_t length, uint32_t flags)
+{
+ unsigned i = 0;
+ uint32_t max_extent = QEMU_ALIGN_DOWN(INT32_MAX, BDRV_SECTOR_SIZE);
This is too small of a granularity wrong when the server advertised 4k
alignment during NBD_OPT_GO; it should probably refer to
bs->bl.request_alignment.
In fact, we can just use INT32_MAX. The dirty bitmap has a granularity
at least as large as the sector size, but no smaller than the
request_alignment. We don't have to worry about alignment here, as the
extents will already be naturally aligned when converting from the
bitmap into extents in the caller.
Oh, I see. The NBD protocol can only ask for a length of up to 32 bits,
but if you learn via bitmap query that the entire rest of the image has
the same state, you can indeed call add_extents() with a value larger
than 32 bits, that needs to be fragmented back down into sub-32-bit
chunks. INT32_MAX isn't quite right, but rounding may still pick the
wrong granularity on an export with 4k alignment; however, INT32_MAX +
1U is just fine, and unlikely to run into alignment issues.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org