In 4146b46c42e0989cb5842e04d88ab6ccb1713a48 (block: Produce zeros when protocols reading beyond end of file), we break qemu-iotests ./check -qcow2 022. This happens because qcow2 temporarily sets ->growable = 1 for vmstate accesses (which are stored beyond the end of regular image data).
We introduce the bs->zero_beyond_eof to allow qcow2_load_vmstate() to disable ->zero_beyond_eof temporarily in addition to enable ->growable. Suggested-by: Stefan Hajnoczi <stefa...@redhat.com> Signed-off-by: Asias He <as...@redhat.com> --- block.c | 5 ++++- block/qcow2.c | 3 +++ include/block/block_int.h | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index f3cd9fb..3a320d5 100644 --- a/block.c +++ b/block.c @@ -868,6 +868,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, QDECREF(options); bs->growable = 1; + bs->zero_beyond_eof = true; *pbs = bs; return 0; @@ -978,6 +979,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, } bs->options = options; + bs->zero_beyond_eof = true; options = qdict_clone_shallow(options); /* For snapshot=on, create a temporary qcow2 overlay */ @@ -1402,6 +1404,7 @@ void bdrv_close(BlockDriverState *bs) bs->valid_key = 0; bs->sg = 0; bs->growable = 0; + bs->zero_beyond_eof = false; QDECREF(bs->options); bs->options = NULL; @@ -2544,7 +2547,7 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, } } - if (!bs->growable) { + if (!(bs->zero_beyond_eof && bs->growable)) { ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); } else { /* Read zeros after EOF of growable BDSes */ diff --git a/block/qcow2.c b/block/qcow2.c index 3376901..14e863d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1722,12 +1722,15 @@ static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf, { BDRVQcowState *s = bs->opaque; int growable = bs->growable; + bool zero_beyond_eof = bs->zero_beyond_eof; int ret; BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD); bs->growable = 1; + bs->zero_beyond_eof = false; ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size); bs->growable = growable; + bs->zero_beyond_eof = zero_beyond_eof; return ret; } diff --git a/include/block/block_int.h b/include/block/block_int.h index e45f2a0..74b0689 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -281,6 +281,9 @@ struct BlockDriverState { /* Whether the disk can expand beyond total_sectors */ int growable; + /* Whether produces zeros when read beyond eof */ + bool zero_beyond_eof; + /* the memory alignment required for the buffers handled by this driver */ int buffer_alignment; -- 1.8.3.1