mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03:55 -06:00
block: Convert bdrv_get_block_status_above() to bytes
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 name of the function from bdrv_get_block_status_above() to bdrv_block_status_above() ensures that the compiler enforces that all callers are updated. Likewise, since it a byte interface allows an offset mapping that might not be sector aligned, split the mapping out of the return value and into a pass-by-reference parameter. For now, the io.c layer still assert()s that all uses are sector-aligned, but that can be relaxed when a later patch implements byte-based block status in the drivers. For the most part this patch is just the addition of scaling at the callers followed by inverse scaling at bdrv_block_status(), plus updates for the new split return interface. But some code, particularly bdrv_block_status(), gets a lot simpler because it no longer has to mess with sectors. Likewise, mirror code no longer computes s->granularity >> BDRV_SECTOR_BITS, and can therefore drop an assertion about alignment because the loop no longer depends on alignment (never mind that we don't really have a driver that reports sub-sector alignments, so it's not really possible to test the effect of sub-sector mirroring). Fix a neighboring assertion to use is_power_of_2 while there. For ease of review, bdrv_get_block_status() was tackled separately. Signed-off-by: Eric Blake <eblake@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
5b648c67e3
commit
3182664220
5 changed files with 57 additions and 103 deletions
49
qemu-img.c
49
qemu-img.c
|
@ -1226,7 +1226,7 @@ static int img_compare(int argc, char **argv)
|
|||
BlockDriverState *bs1, *bs2;
|
||||
int64_t total_sectors1, total_sectors2;
|
||||
uint8_t *buf1 = NULL, *buf2 = NULL;
|
||||
int pnum1, pnum2;
|
||||
int64_t pnum1, pnum2;
|
||||
int allocated1, allocated2;
|
||||
int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
|
||||
bool progress = false, quiet = false, strict = false;
|
||||
|
@ -1374,15 +1374,17 @@ static int img_compare(int argc, char **argv)
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
int64_t status1, status2;
|
||||
int status1, status2;
|
||||
|
||||
nb_sectors = sectors_to_process(total_sectors, sector_num);
|
||||
if (nb_sectors <= 0) {
|
||||
break;
|
||||
}
|
||||
status1 = bdrv_get_block_status_above(bs1, NULL, sector_num,
|
||||
total_sectors1 - sector_num,
|
||||
&pnum1, NULL);
|
||||
status1 = bdrv_block_status_above(bs1, NULL,
|
||||
sector_num * BDRV_SECTOR_SIZE,
|
||||
(total_sectors1 - sector_num) *
|
||||
BDRV_SECTOR_SIZE,
|
||||
&pnum1, NULL, NULL);
|
||||
if (status1 < 0) {
|
||||
ret = 3;
|
||||
error_report("Sector allocation test failed for %s", filename1);
|
||||
|
@ -1390,25 +1392,29 @@ static int img_compare(int argc, char **argv)
|
|||
}
|
||||
allocated1 = status1 & BDRV_BLOCK_ALLOCATED;
|
||||
|
||||
status2 = bdrv_get_block_status_above(bs2, NULL, sector_num,
|
||||
total_sectors2 - sector_num,
|
||||
&pnum2, NULL);
|
||||
status2 = bdrv_block_status_above(bs2, NULL,
|
||||
sector_num * BDRV_SECTOR_SIZE,
|
||||
(total_sectors2 - sector_num) *
|
||||
BDRV_SECTOR_SIZE,
|
||||
&pnum2, NULL, NULL);
|
||||
if (status2 < 0) {
|
||||
ret = 3;
|
||||
error_report("Sector allocation test failed for %s", filename2);
|
||||
goto out;
|
||||
}
|
||||
allocated2 = status2 & BDRV_BLOCK_ALLOCATED;
|
||||
/* TODO: Relax this once comparison is byte-based, and we no longer
|
||||
* have to worry about sector alignment */
|
||||
assert(QEMU_IS_ALIGNED(pnum1 | pnum2, BDRV_SECTOR_SIZE));
|
||||
if (pnum1) {
|
||||
nb_sectors = MIN(nb_sectors, pnum1);
|
||||
nb_sectors = MIN(nb_sectors, pnum1 >> BDRV_SECTOR_BITS);
|
||||
}
|
||||
if (pnum2) {
|
||||
nb_sectors = MIN(nb_sectors, pnum2);
|
||||
nb_sectors = MIN(nb_sectors, pnum2 >> BDRV_SECTOR_BITS);
|
||||
}
|
||||
|
||||
if (strict) {
|
||||
if ((status1 & ~BDRV_BLOCK_OFFSET_MASK) !=
|
||||
(status2 & ~BDRV_BLOCK_OFFSET_MASK)) {
|
||||
if (status1 != status2) {
|
||||
ret = 1;
|
||||
qprintf(quiet, "Strict mode: Offset %" PRId64
|
||||
" block status mismatch!\n",
|
||||
|
@ -1417,7 +1423,7 @@ static int img_compare(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
if ((status1 & BDRV_BLOCK_ZERO) && (status2 & BDRV_BLOCK_ZERO)) {
|
||||
nb_sectors = MIN(pnum1, pnum2);
|
||||
nb_sectors = DIV_ROUND_UP(MIN(pnum1, pnum2), BDRV_SECTOR_SIZE);
|
||||
} else if (allocated1 == allocated2) {
|
||||
if (allocated1) {
|
||||
ret = blk_pread(blk1, sector_num << BDRV_SECTOR_BITS, buf1,
|
||||
|
@ -1589,8 +1595,8 @@ static void convert_select_part(ImgConvertState *s, int64_t sector_num,
|
|||
|
||||
static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
|
||||
{
|
||||
int64_t ret, src_cur_offset;
|
||||
int n, src_cur;
|
||||
int64_t src_cur_offset;
|
||||
int ret, n, src_cur;
|
||||
|
||||
convert_select_part(s, sector_num, &src_cur, &src_cur_offset);
|
||||
|
||||
|
@ -1598,23 +1604,24 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
|
|||
n = MIN(s->total_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS);
|
||||
|
||||
if (s->sector_next_status <= sector_num) {
|
||||
int64_t count = n * BDRV_SECTOR_SIZE;
|
||||
|
||||
if (s->target_has_backing) {
|
||||
int64_t count = n * BDRV_SECTOR_SIZE;
|
||||
|
||||
ret = bdrv_block_status(blk_bs(s->src[src_cur]),
|
||||
(sector_num - src_cur_offset) *
|
||||
BDRV_SECTOR_SIZE,
|
||||
count, &count, NULL, NULL);
|
||||
assert(ret < 0 || QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
|
||||
n = count >> BDRV_SECTOR_BITS;
|
||||
} else {
|
||||
ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL,
|
||||
sector_num - src_cur_offset,
|
||||
n, &n, NULL);
|
||||
ret = bdrv_block_status_above(blk_bs(s->src[src_cur]), NULL,
|
||||
(sector_num - src_cur_offset) *
|
||||
BDRV_SECTOR_SIZE,
|
||||
count, &count, NULL, NULL);
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
n = DIV_ROUND_UP(count, BDRV_SECTOR_SIZE);
|
||||
|
||||
if (ret & BDRV_BLOCK_ZERO) {
|
||||
s->status = BLK_ZERO;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue