Skip to content

Commit 787993a

Browse files
ebblakekevmw
authored andcommitted
qcow: Switch get_cluster_offset to be byte-based
We are gradually moving away from sector-based interfaces, towards byte-based. Make the change for the internal helper function get_cluster_offset(), by changing n_start and n_end to be byte offsets rather than sector indices within the cluster being allocated. However, assert that these values are still sector-aligned (at least qcrypto_block_encrypt() still wants that). For now we get that alignment for free because we still use sector-based driver callbacks. A later patch will then switch the qcow driver as a whole over to byte-based operation; but will still leave things at sector alignments as it is not worth auditing the qcow image format to worry about sub-sector requests. Signed-off-by: Eric Blake <[email protected]> Reviewed-by: Jeff Cody <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent d08c2a2 commit 787993a

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

block/qcow.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,8 @@ static int qcow_reopen_prepare(BDRVReopenState *state,
345345
*
346346
* 0 to not allocate.
347347
*
348-
* 1 to allocate a normal cluster (for sector indexes 'n_start' to
349-
* 'n_end')
348+
* 1 to allocate a normal cluster (for sector-aligned byte offsets 'n_start'
349+
* to 'n_end' within the cluster)
350350
*
351351
* 2 to allocate a compressed cluster of size
352352
* 'compressed_size'. 'compressed_size' must be > 0 and <
@@ -440,9 +440,10 @@ static int get_cluster_offset(BlockDriverState *bs,
440440
if (!allocate)
441441
return 0;
442442
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
443+
assert(QEMU_IS_ALIGNED(n_start | n_end, BDRV_SECTOR_SIZE));
443444
/* allocate a new cluster */
444445
if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
445-
(n_end - n_start) < s->cluster_sectors) {
446+
(n_end - n_start) < s->cluster_size) {
446447
/* if the cluster is already compressed, we must
447448
decompress it in the case it is not completely
448449
overwritten */
@@ -480,25 +481,25 @@ static int get_cluster_offset(BlockDriverState *bs,
480481
/* if encrypted, we must initialize the cluster
481482
content which won't be written */
482483
if (bs->encrypted &&
483-
(n_end - n_start) < s->cluster_sectors) {
484-
uint64_t start_sect;
484+
(n_end - n_start) < s->cluster_size) {
485+
uint64_t start_offset;
485486
assert(s->crypto);
486-
start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
487-
for(i = 0; i < s->cluster_sectors; i++) {
487+
start_offset = offset & ~(s->cluster_size - 1);
488+
for (i = 0; i < s->cluster_size; i += BDRV_SECTOR_SIZE) {
488489
if (i < n_start || i >= n_end) {
489-
memset(s->cluster_data, 0x00, 512);
490+
memset(s->cluster_data, 0x00, BDRV_SECTOR_SIZE);
490491
if (qcrypto_block_encrypt(s->crypto,
491-
(start_sect + i) *
492-
BDRV_SECTOR_SIZE,
492+
start_offset + i,
493493
s->cluster_data,
494494
BDRV_SECTOR_SIZE,
495495
NULL) < 0) {
496496
return -EIO;
497497
}
498498
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
499499
ret = bdrv_pwrite(bs->file,
500-
cluster_offset + i * 512,
501-
s->cluster_data, 512);
500+
cluster_offset + i,
501+
s->cluster_data,
502+
BDRV_SECTOR_SIZE);
502503
if (ret < 0) {
503504
return ret;
504505
}
@@ -758,8 +759,8 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
758759
n = nb_sectors;
759760
}
760761
ret = get_cluster_offset(bs, sector_num << 9, 1, 0,
761-
index_in_cluster,
762-
index_in_cluster + n, &cluster_offset);
762+
index_in_cluster << 9,
763+
(index_in_cluster + n) << 9, &cluster_offset);
763764
if (ret < 0) {
764765
break;
765766
}

0 commit comments

Comments
 (0)