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>
This commit is contained in:
parent
9b92fbcf45
commit
8644476e51
15
block/io.c
15
block/io.c
@ -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,
|
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
|
||||||
BDRV_REQUEST_MAX_BYTES);
|
BDRV_REQUEST_MAX_BYTES);
|
||||||
unsigned int progress = 0;
|
unsigned int progress = 0;
|
||||||
|
bool skip_write;
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
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
|
/* 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
|
* 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
|
* would be obtained anyway, but internally by the copy-on-read code. As
|
||||||
@ -1274,10 +1281,15 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
|||||||
while (cluster_bytes) {
|
while (cluster_bytes) {
|
||||||
int64_t pnum;
|
int64_t pnum;
|
||||||
|
|
||||||
|
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,
|
ret = bdrv_is_allocated(bs, cluster_offset,
|
||||||
MIN(cluster_bytes, max_transfer), &pnum);
|
MIN(cluster_bytes, max_transfer), &pnum);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* Safe to treat errors in querying allocation as if
|
/*
|
||||||
|
* Safe to treat errors in querying allocation as if
|
||||||
* unallocated; we'll probably fail again soon on the
|
* unallocated; we'll probably fail again soon on the
|
||||||
* read, but at least that will set a decent errno.
|
* read, but at least that will set a decent errno.
|
||||||
*/
|
*/
|
||||||
@ -1291,6 +1303,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(skip_bytes < pnum);
|
assert(skip_bytes < pnum);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
QEMUIOVector local_qiov;
|
QEMUIOVector local_qiov;
|
||||||
|
Loading…
Reference in New Issue
Block a user