Commit d0ceea88 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

qemu-img map: Don't limit block status request size



Limiting each loop iteration of qemu-img map to 1 GB was arbitrary from
the beginning, though it only cut the maximum in half then because the
interface was a signed 32 bit byte count. These days, bdrv_block_status
supports a 64 bit byte count, so the arbitrary limit is even worse.

On file-posix, bdrv_block_status() eventually maps to SEEK_HOLE and
SEEK_DATA, which don't support a limit, but always do all of the work
necessary to find the start of the next hole/data. Much of this work may
be repeated if we don't use this information fully, but query with an
only slightly larger offset in the next loop iteration. Therefore, if
bdrv_block_status() is called in a loop, it should always pass the
full number of bytes that the whole loop is interested in.

This removes the arbitrary limit and speeds up 'qemu-img map'
significantly on heavily fragmented images.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Message-Id: <20200707144629.51235-1-kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 4b196cd1
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -3210,12 +3210,9 @@ static int img_map(int argc, char **argv)
    curr.start = start_offset;
    while (curr.start + curr.length < length) {
        int64_t offset = curr.start + curr.length;
        int64_t n;
        int64_t n = length - offset;

        /* Probe up to 1 GiB at a time.  */
        n = MIN(1 * GiB, length - offset);
        ret = get_block_status(bs, offset, n, &next);

        if (ret < 0) {
            error_report("Could not read file metadata: %s", strerror(-ret));
            goto out;