[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-block] [PATCH 16/17] block: Make bdrv_is_allocated() byte-base
From: |
John Snow |
Subject: |
Re: [Qemu-block] [PATCH 16/17] block: Make bdrv_is_allocated() byte-based |
Date: |
Wed, 19 Apr 2017 16:32:55 -0400 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.0 |
On 04/11/2017 06:29 PM, Eric Blake wrote:
> We are gradually moving away from sector-based interfaces, towards
> byte-based. In the common case, allocation is unlikely to ever use
> values that are not naturally sector-aligned, but it is possible
> that byte-based values will let us be more precise about allocation
> at the end of an unaligned file that can do byte-based access.
>
> Changing the signature of the function to use int64_t *pnum ensures
> that the compiler enforces that all callers are updated. For now,
> the io.c layer still assert()s that all callers are sector-aligned,
> but that can be relaxed when a later patch implements byte-based
> block status. Therefore, for the most part this patch is just the
> addition of scaling at the callers followed by inverse scaling at
> bdrv_is_allocated(). But some code, particularly bdrv_commit(),
> gets a lot simpler because it no longer has to mess with sectors;
> also, it is now possible to pass NULL if the caller does not care
> how much of the image is allocated beyond the initial offset.
>
> For ease of review, bdrv_is_allocated_above() will be tackled
> separately.
>
> Signed-off-by: Eric Blake <address@hidden>
> ---
> include/block/block.h | 4 ++--
> block/backup.c | 17 +++++----------
> block/commit.c | 21 ++++++++-----------
> block/io.c | 49 +++++++++++++++++++++++++++++--------------
> block/stream.c | 5 +++--
> block/vvfat.c | 34 +++++++++++++++++-------------
> migration/block.c | 9 ++++----
> qemu-img.c | 5 ++++-
> qemu-io-cmds.c | 57
> +++++++++++++++++++++++++--------------------------
> 9 files changed, 110 insertions(+), 91 deletions(-)
>
> diff --git a/include/block/block.h b/include/block/block.h
> index b5289f7..8641149 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -422,8 +422,8 @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs,
> int64_t sector_num,
> int nb_sectors, int *pnum,
> BlockDriverState **file);
> -int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int
> nb_sectors,
> - int *pnum);
> +int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
> + int64_t *pnum);
> int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
> int64_t sector_num, int nb_sectors, int *pnum);
>
> diff --git a/block/backup.c b/block/backup.c
> index 2a51e8b..63ca208 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -47,12 +47,6 @@ typedef struct BackupBlockJob {
> QLIST_HEAD(, CowRequest) inflight_reqs;
> } BackupBlockJob;
>
> -/* Size of a cluster in sectors, instead of bytes. */
> -static inline int64_t cluster_size_sectors(BackupBlockJob *job)
> -{
> - return job->cluster_size / BDRV_SECTOR_SIZE;
> -}
> -
> /* See if in-flight requests overlap and wait for them to complete */
> static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
> int64_t start,
> @@ -433,7 +427,6 @@ static void coroutine_fn backup_run(void *opaque)
> BackupCompleteData *data;
> BlockDriverState *bs = blk_bs(job->common.blk);
> int64_t offset;
> - int64_t sectors_per_cluster = cluster_size_sectors(job);
> int ret = 0;
>
> QLIST_INIT(&job->inflight_reqs);
> @@ -465,12 +458,13 @@ static void coroutine_fn backup_run(void *opaque)
> }
>
> if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
> - int i, n;
> + int i;
> + int64_t n;
>
> /* Check to see if these blocks are already in the
> * backing file. */
>
> - for (i = 0; i < sectors_per_cluster;) {
> + for (i = 0; i < job->cluster_size;) {
> /* bdrv_is_allocated() only returns true/false based
> * on the first set of sectors it comes across that
> * are are all in the same state.
> @@ -478,9 +472,8 @@ static void coroutine_fn backup_run(void *opaque)
> * backup cluster length. We end up copying more than
> * needed but at some point that is always the case. */
> alloced =
> - bdrv_is_allocated(bs,
> - (offset >> BDRV_SECTOR_BITS) + i,
> - sectors_per_cluster - i, &n);
> + bdrv_is_allocated(bs, offset + i,
> + job->cluster_size - i, &n);
> i += n;
>
> if (alloced || n == 0) {
> diff --git a/block/commit.c b/block/commit.c
> index b7d3e60..4d6bb2a 100644
> --- a/block/commit.c
> +++ b/block/commit.c
> @@ -429,7 +429,7 @@ fail:
> }
>
>
> -#define COMMIT_BUF_SECTORS 2048
> +#define COMMIT_BUF_SIZE (2048 * BDRV_SECTOR_SIZE)
>
> /* commit COW file into the raw image */
> int bdrv_commit(BlockDriverState *bs)
> @@ -438,8 +438,9 @@ int bdrv_commit(BlockDriverState *bs)
> BlockDriverState *backing_file_bs = NULL;
> BlockDriverState *commit_top_bs = NULL;
> BlockDriver *drv = bs->drv;
> - int64_t sector, total_sectors, length, backing_length;
> - int n, ro, open_flags;
> + int64_t offset, length, backing_length;
> + int ro, open_flags;
> + int64_t n;
> int ret = 0;
> uint8_t *buf = NULL;
> Error *local_err = NULL;
> @@ -517,30 +518,26 @@ int bdrv_commit(BlockDriverState *bs)
> }
> }
>
> - total_sectors = length >> BDRV_SECTOR_BITS;
> -
> /* blk_try_blockalign() for src will choose an alignment that works for
> * backing as well, so no need to compare the alignment manually. */
> - buf = blk_try_blockalign(src, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
> + buf = blk_try_blockalign(src, COMMIT_BUF_SIZE);
> if (buf == NULL) {
> ret = -ENOMEM;
> goto ro_cleanup;
> }
>
> - for (sector = 0; sector < total_sectors; sector += n) {
> - ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
> + for (offset = 0; offset < length; offset += n) {
> + ret = bdrv_is_allocated(bs, offset, COMMIT_BUF_SIZE, &n);
> if (ret < 0) {
> goto ro_cleanup;
> }
> if (ret) {
> - ret = blk_pread(src, sector * BDRV_SECTOR_SIZE, buf,
> - n * BDRV_SECTOR_SIZE);
> + ret = blk_pread(src, offset, buf, n);
> if (ret < 0) {
> goto ro_cleanup;
> }
>
> - ret = blk_pwrite(backing, sector * BDRV_SECTOR_SIZE, buf,
> - n * BDRV_SECTOR_SIZE, 0);
> + ret = blk_pwrite(backing, offset, buf, n, 0);
> if (ret < 0) {
> goto ro_cleanup;
> }
> diff --git a/block/io.c b/block/io.c
> index 8706bfa..438a493 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -1054,14 +1054,15 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild
> *child,
> int64_t start_sector = offset >> BDRV_SECTOR_BITS;
> int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
> unsigned int nb_sectors = end_sector - start_sector;
> - int pnum;
> + int64_t pnum;
>
> - ret = bdrv_is_allocated(bs, start_sector, nb_sectors, &pnum);
> + ret = bdrv_is_allocated(bs, start_sector << BDRV_SECTOR_BITS,
> + nb_sectors << BDRV_SECTOR_BITS, &pnum);
> if (ret < 0) {
> goto out;
> }
>
> - if (!ret || pnum != nb_sectors) {
> + if (!ret || pnum != nb_sectors << BDRV_SECTOR_BITS) {
> ret = bdrv_co_do_copy_on_readv(child, offset, bytes, qiov);
> goto out;
> }
> @@ -1903,15 +1904,26 @@ int64_t bdrv_get_block_status(BlockDriverState *bs,
> sector_num, nb_sectors, pnum, file);
> }
>
> -int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
> - int nb_sectors, int *pnum)
> +int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
> + int64_t bytes, int64_t *pnum)
> {
> BlockDriverState *file;
> - int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum,
> - &file);
> + int64_t sector_num = offset >> BDRV_SECTOR_BITS;
> + int nb_sectors = bytes >> BDRV_SECTOR_BITS;
> + int64_t ret;
> + int psectors;
> +
> + assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
> + assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE) &&
> + bytes < INT_MAX * BDRV_SECTOR_SIZE);
> + ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &psectors,
> + &file);
> if (ret < 0) {
> return ret;
> }
> + if (pnum) {
> + *pnum = psectors * BDRV_SECTOR_SIZE;
> + }
> return !!(ret & BDRV_BLOCK_ALLOCATED);
> }
>
> @@ -1920,7 +1932,8 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState
> *bs, int64_t sector_num,
> *
> * Return true if the given sector is allocated in any image between
> * BASE and TOP (inclusive). BASE can be NULL to check if the given
> - * sector is allocated in any image of the chain. Return false otherwise.
> + * sector is allocated in any image of the chain. Return false otherwise,
> + * or negative errno on failure.
> *
> * 'pnum' is set to the number of sectors (including and immediately
> following
> * the specified sector) that are known to be in the same
> @@ -1937,13 +1950,19 @@ int bdrv_is_allocated_above(BlockDriverState *top,
>
> intermediate = top;
> while (intermediate && intermediate != base) {
> - int pnum_inter;
> - ret = bdrv_is_allocated(intermediate, sector_num, nb_sectors,
> + int64_t pnum_inter;
> + int psectors_inter;
> +
> + ret = bdrv_is_allocated(intermediate, sector_num * BDRV_SECTOR_SIZE,
> + nb_sectors * BDRV_SECTOR_SIZE,
> &pnum_inter);
> if (ret < 0) {
> return ret;
> - } else if (ret) {
> - *pnum = pnum_inter;
> + }
> + assert(pnum_inter < INT_MAX * BDRV_SECTOR_SIZE);
> + psectors_inter = pnum_inter >> BDRV_SECTOR_BITS;
> + if (ret) {
> + *pnum = psectors_inter;
> return 1;
> }
>
> @@ -1953,10 +1972,10 @@ int bdrv_is_allocated_above(BlockDriverState *top,
> *
> * [sector_num+x, nr_sectors] allocated.
> */
> - if (n > pnum_inter &&
> + if (n > psectors_inter &&
> (intermediate == top ||
> - sector_num + pnum_inter < intermediate->total_sectors)) {
> - n = pnum_inter;
> + sector_num + psectors_inter < intermediate->total_sectors)) {
> + n = psectors_inter;
> }
>
> intermediate = backing_bs(intermediate);
> diff --git a/block/stream.c b/block/stream.c
> index 3ed4fef..85502eb 100644
> --- a/block/stream.c
> +++ b/block/stream.c
> @@ -138,6 +138,7 @@ static void coroutine_fn stream_run(void *opaque)
>
> for ( ; offset < s->common.len; offset += n * BDRV_SECTOR_SIZE) {
> bool copy;
> + int64_t count = 0;
>
> /* Note that even when no rate limit is applied we need to yield
> * with no pending I/O here so that bdrv_drain_all() returns.
> @@ -149,8 +150,8 @@ static void coroutine_fn stream_run(void *opaque)
>
> copy = false;
>
> - ret = bdrv_is_allocated(bs, offset / BDRV_SECTOR_SIZE,
> - STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
> + ret = bdrv_is_allocated(bs, offset, STREAM_BUFFER_SIZE, &count);
> + n = DIV_ROUND_UP(count, BDRV_SECTOR_SIZE);
> if (ret == 1) {
> /* Allocated in the top, no need to copy. */
> } else if (ret >= 0) {
> diff --git a/block/vvfat.c b/block/vvfat.c
> index af5153d..bef2056 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -1393,24 +1393,27 @@ static int vvfat_read(BlockDriverState *bs, int64_t
> sector_num,
> if (sector_num >= bs->total_sectors)
> return -1;
> if (s->qcow) {
> - int n;
> + int64_t n;
> int ret;
> - ret = bdrv_is_allocated(s->qcow->bs, sector_num,
> - nb_sectors - i, &n);
> + ret = bdrv_is_allocated(s->qcow->bs, sector_num *
> BDRV_SECTOR_SIZE,
> + (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
> if (ret < 0) {
> return ret;
> }
> if (ret) {
> - DLOG(fprintf(stderr, "sectors %d+%d allocated\n",
> - (int)sector_num, n));
> - if (bdrv_read(s->qcow, sector_num, buf + i * 0x200, n)) {
> + DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
> + " allocated\n", sector_num,
> + n >> BDRV_SECTOR_BITS));
> + if (bdrv_read(s->qcow, sector_num, buf + i * 0x200,
> + n >> BDRV_SECTOR_BITS)) {
> return -1;
> }
> - i += n - 1;
> - sector_num += n - 1;
> + i += (n >> BDRV_SECTOR_BITS) - 1;
> + sector_num += (n >> BDRV_SECTOR_BITS) - 1;
> continue;
> }
> -DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
> + DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
> + sector_num));
> }
> if(sector_num<s->faked_sectors) {
> if(sector_num<s->first_sectors_number)
> @@ -1678,7 +1681,7 @@ static inline bool cluster_was_modified(BDRVVVFATState
> *s,
> uint32_t cluster_num)
> {
> int was_modified = 0;
> - int i, dummy;
> + int i;
>
> if (s->qcow == NULL) {
> return 0;
> @@ -1686,8 +1689,9 @@ static inline bool cluster_was_modified(BDRVVVFATState
> *s,
>
> for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
> was_modified = bdrv_is_allocated(s->qcow->bs,
> - cluster2sector(s, cluster_num) + i,
> - 1, &dummy);
> + (cluster2sector(s, cluster_num) +
> + i) * BDRV_SECTOR_SIZE,
> + BDRV_SECTOR_SIZE, NULL);
> }
>
> /*
> @@ -1834,7 +1838,7 @@ static uint32_t
> get_cluster_count_for_direntry(BDRVVVFATState* s,
> }
>
> if (copy_it) {
> - int i, dummy;
> + int i;
> /*
> * This is horribly inefficient, but that is okay, since
> * it is rarely executed, if at all.
> @@ -1845,7 +1849,9 @@ static uint32_t
> get_cluster_count_for_direntry(BDRVVVFATState* s,
> for (i = 0; i < s->sectors_per_cluster; i++) {
> int res;
>
> - res = bdrv_is_allocated(s->qcow->bs, offset + i, 1,
> &dummy);
> + res = bdrv_is_allocated(s->qcow->bs,
> + (offset + i) * BDRV_SECTOR_SIZE,
> + BDRV_SECTOR_SIZE, NULL);
> if (res < 0) {
> return -1;
> }
> diff --git a/migration/block.c b/migration/block.c
> index 7734ff7..18d50ff 100644
> --- a/migration/block.c
> +++ b/migration/block.c
> @@ -36,7 +36,7 @@
> #define BLK_MIG_FLAG_PROGRESS 0x04
> #define BLK_MIG_FLAG_ZERO_BLOCK 0x08
>
> -#define MAX_IS_ALLOCATED_SEARCH 65536
> +#define MAX_IS_ALLOCATED_SEARCH (65536 * BDRV_SECTOR_SIZE)
>
> #define MAX_INFLIGHT_IO 512
>
> @@ -272,6 +272,7 @@ static int mig_save_device_bulk(QEMUFile *f,
> BlkMigDevState *bmds)
> BlockBackend *bb = bmds->blk;
> BlkMigBlock *blk;
> int nr_sectors;
> + int64_t count;
>
> if (bmds->shared_base) {
> qemu_mutex_lock_iothread();
> @@ -279,9 +280,9 @@ static int mig_save_device_bulk(QEMUFile *f,
> BlkMigDevState *bmds)
> /* Skip unallocated sectors; intentionally treats failure as
> * an allocated sector */
> while (cur_sector < total_sectors &&
> - !bdrv_is_allocated(blk_bs(bb), cur_sector,
> - MAX_IS_ALLOCATED_SEARCH, &nr_sectors)) {
> - cur_sector += nr_sectors;
> + !bdrv_is_allocated(blk_bs(bb), cur_sector * BDRV_SECTOR_SIZE,
> + MAX_IS_ALLOCATED_SEARCH, &count)) {
> + cur_sector += DIV_ROUND_UP(count, BDRV_SECTOR_SIZE);
> }
Let's try asking again with the right vocabulary:
OK, so I guess the idea is that we definitely shouldn't ever have a
partially allocated sector; so I suppose this ROUND_UP is just a precaution?
What would it mean if this actually DID round up? Would we miss
transmitting a fraction of a sector because we assumed it was unallocated?
In other places, you scale down with X / BDRV_SECTOR_SIZE or an
equivalent bitshift, why does this receive a round *up* treatment?
Are we considering a future in which this function might actually give
us some unaligned answers? Do we need to re-audit all of the callers at
that point to make sure they cope appropriately?
--js
> aio_context_release(blk_get_aio_context(bb));
> qemu_mutex_unlock_iothread();
> diff --git a/qemu-img.c b/qemu-img.c
> index 37c2894..2f21d69 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -3207,6 +3207,7 @@ static int img_rebase(int argc, char **argv)
> int64_t new_backing_num_sectors = 0;
> uint64_t sector;
> int n;
> + int64_t count;
> float local_progress = 0;
>
> buf_old = blk_blockalign(blk, IO_BUF_SIZE);
> @@ -3254,12 +3255,14 @@ static int img_rebase(int argc, char **argv)
> }
>
> /* If the cluster is allocated, we don't need to take action */
> - ret = bdrv_is_allocated(bs, sector, n, &n);
> + ret = bdrv_is_allocated(bs, sector << BDRV_SECTOR_BITS,
> + n << BDRV_SECTOR_BITS, &count);
> if (ret < 0) {
> error_report("error while reading image metadata: %s",
> strerror(-ret));
> goto out;
> }
> + n = DIV_ROUND_UP(count, BDRV_SECTOR_SIZE);
> if (ret) {
> continue;
> }
> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index 0ac7457..62278ea 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c
> @@ -1760,12 +1760,12 @@ out:
> static int alloc_f(BlockBackend *blk, int argc, char **argv)
> {
> BlockDriverState *bs = blk_bs(blk);
> - int64_t offset, sector_num, nb_sectors, remaining, bytes;
> + int64_t offset, start, remaining, bytes;
> char s1[64];
> - int num, ret;
> - int64_t sum_alloc;
> + int ret;
> + int64_t num, sum_alloc;
>
> - offset = cvtnum(argv[1]);
> + start = offset = cvtnum(argv[1]);
> if (offset < 0) {
> print_cvtnum_err(offset, argv[1]);
> return 0;
> @@ -1793,32 +1793,30 @@ static int alloc_f(BlockBackend *blk, int argc, char
> **argv)
> bytes);
> return 0;
> }
> - nb_sectors = bytes >> BDRV_SECTOR_BITS;
>
> - remaining = nb_sectors;
> + remaining = bytes;
> sum_alloc = 0;
> - sector_num = offset >> 9;
> while (remaining) {
> - ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
> + ret = bdrv_is_allocated(bs, offset, remaining, &num);
> if (ret < 0) {
> printf("is_allocated failed: %s\n", strerror(-ret));
> return 0;
> }
> - sector_num += num;
> + offset += num;
> remaining -= num;
> if (ret) {
> sum_alloc += num;
> }
> if (num == 0) {
> - nb_sectors -= remaining;
> + bytes -= remaining;
> remaining = 0;
> }
> }
>
> - cvtstr(offset, s1, sizeof(s1));
> + cvtstr(start, s1, sizeof(s1));
>
> printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
> - sum_alloc << BDRV_SECTOR_BITS, nb_sectors << BDRV_SECTOR_BITS,
> s1);
> + sum_alloc, bytes, s1);
> return 0;
> }
>
> @@ -1833,14 +1831,15 @@ static const cmdinfo_t alloc_cmd = {
> };
>
>
> -static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
> - int64_t nb_sectors, int64_t *pnum)
> +static int map_is_allocated(BlockDriverState *bs, int64_t offset,
> + int64_t bytes, int64_t *pnum)
> {
> - int num, num_checked;
> + int64_t num;
> + int num_checked;
> int ret, firstret;
>
> - num_checked = MIN(nb_sectors, INT_MAX);
> - ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
> + num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
> + ret = bdrv_is_allocated(bs, offset, num_checked, &num);
> if (ret < 0) {
> return ret;
> }
> @@ -1848,12 +1847,12 @@ static int map_is_allocated(BlockDriverState *bs,
> int64_t sector_num,
> firstret = ret;
> *pnum = num;
>
> - while (nb_sectors > 0 && ret == firstret) {
> - sector_num += num;
> - nb_sectors -= num;
> + while (bytes > 0 && ret == firstret) {
> + offset += num;
> + bytes -= num;
>
> - num_checked = MIN(nb_sectors, INT_MAX);
> - ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
> + num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
> + ret = bdrv_is_allocated(bs, offset, num_checked, &num);
> if (ret == firstret && num) {
> *pnum += num;
> } else {
> @@ -1867,7 +1866,7 @@ static int map_is_allocated(BlockDriverState *bs,
> int64_t sector_num,
> static int map_f(BlockBackend *blk, int argc, char **argv)
> {
> int64_t offset;
> - int64_t nb_sectors, total_sectors;
> + int64_t bytes, total_sectors;
> char s1[64];
> int64_t num;
> int ret;
> @@ -1881,10 +1880,10 @@ static int map_f(BlockBackend *blk, int argc, char
> **argv)
> return 0;
> }
>
> - nb_sectors = total_sectors;
> + bytes = total_sectors * BDRV_SECTOR_SIZE;
>
> do {
> - ret = map_is_allocated(blk_bs(blk), offset, nb_sectors, &num);
> + ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
> if (ret < 0) {
> error_report("Failed to get allocation status: %s",
> strerror(-ret));
> return 0;
> @@ -1894,13 +1893,13 @@ static int map_f(BlockBackend *blk, int argc, char
> **argv)
> }
>
> retstr = ret ? " allocated" : "not allocated";
> - cvtstr(offset << 9ULL, s1, sizeof(s1));
> + cvtstr(offset, s1, sizeof(s1));
> printf("[% 24" PRId64 "] % 16" PRId64 " bytes %s at offset %s
> (%d)\n",
> - offset << 9ULL, num << 9ULL, retstr, s1, ret);
> + offset, num, retstr, s1, ret);
>
> offset += num;
> - nb_sectors -= num;
> - } while (offset < total_sectors);
> + bytes -= num;
> + } while (offset < total_sectors * BDRV_SECTOR_SIZE);
>
> return 0;
> }
>
- [Qemu-block] [PATCH 12/17] backup: Switch BackupBlockJob to byte-based, (continued)
- [Qemu-block] [PATCH 12/17] backup: Switch BackupBlockJob to byte-based, Eric Blake, 2017/04/11
- [Qemu-block] [PATCH 13/17] backup: Switch block_backup.h to byte-based, Eric Blake, 2017/04/11
- [Qemu-block] [PATCH 14/17] backup: Switch backup_do_cow() to byte-based, Eric Blake, 2017/04/11
- [Qemu-block] [PATCH 15/17] backup: Switch backup_run() to byte-based, Eric Blake, 2017/04/11
- [Qemu-block] [PATCH 16/17] block: Make bdrv_is_allocated() byte-based, Eric Blake, 2017/04/11
- Re: [Qemu-block] [PATCH 16/17] block: Make bdrv_is_allocated() byte-based,
John Snow <=
[Qemu-block] [PATCH 17/17] block: Make bdrv_is_allocated_above() byte-based, Eric Blake, 2017/04/11
Re: [Qemu-block] [PATCH 00/17] make bdrv_is_allocated[_above] byte-based, John Snow, 2017/04/17