diff options
author | Max Reitz <mreitz@redhat.com> | 2019-10-01 19:48:26 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2019-10-08 14:28:25 +0100 |
commit | 8644476e51fa33d7ab637b36b1306d0d4c66177c (patch) | |
tree | 2e998bc1cc853fcb7665074003c2630f40aed03b /block/io.c | |
parent | 9b92fbcf45ed6ed1daceba8480b0d9e8a327b5ce (diff) | |
download | qemu-8644476e51fa33d7ab637b36b1306d0d4c66177c.zip qemu-8644476e51fa33d7ab637b36b1306d0d4c66177c.tar.gz qemu-8644476e51fa33d7ab637b36b1306d0d4c66177c.tar.bz2 |
block: Skip COR for inactive nodes
We must not write data to inactive nodes, and a COR is certainly
something we can simply not do without upsetting anyone. So skip COR
operations on inactive nodes.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20191001174827.11081-2-mreitz@redhat.com
Message-Id: <20191001174827.11081-2-mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/io.c')
-rw-r--r-- | block/io.c | 41 |
1 files changed, 27 insertions, 14 deletions
@@ -1246,11 +1246,18 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, BDRV_REQUEST_MAX_BYTES); unsigned int progress = 0; + bool skip_write; if (!drv) { return -ENOMEDIUM; } + /* + * Do not write anything when the BDS is inactive. That is not + * allowed, and it would not help. + */ + skip_write = (bs->open_flags & BDRV_O_INACTIVE); + /* FIXME We cannot require callers to have write permissions when all they * are doing is a read request. If we did things right, write permissions * would be obtained anyway, but internally by the copy-on-read code. As @@ -1274,23 +1281,29 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, while (cluster_bytes) { int64_t pnum; - ret = bdrv_is_allocated(bs, cluster_offset, - MIN(cluster_bytes, max_transfer), &pnum); - if (ret < 0) { - /* Safe to treat errors in querying allocation as if - * unallocated; we'll probably fail again soon on the - * read, but at least that will set a decent errno. - */ + if (skip_write) { + ret = 1; /* "already allocated", so nothing will be copied */ pnum = MIN(cluster_bytes, max_transfer); - } + } else { + ret = bdrv_is_allocated(bs, cluster_offset, + MIN(cluster_bytes, max_transfer), &pnum); + if (ret < 0) { + /* + * Safe to treat errors in querying allocation as if + * unallocated; we'll probably fail again soon on the + * read, but at least that will set a decent errno. + */ + pnum = MIN(cluster_bytes, max_transfer); + } - /* Stop at EOF if the image ends in the middle of the cluster */ - if (ret == 0 && pnum == 0) { - assert(progress >= bytes); - break; - } + /* Stop at EOF if the image ends in the middle of the cluster */ + if (ret == 0 && pnum == 0) { + assert(progress >= bytes); + break; + } - assert(skip_bytes < pnum); + assert(skip_bytes < pnum); + } if (ret <= 0) { QEMUIOVector local_qiov; |