diff options
author | Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> | 2020-12-16 09:16:57 +0300 |
---|---|---|
committer | Max Reitz <mreitz@redhat.com> | 2021-01-26 14:36:37 +0100 |
commit | 897dd0ec4fdea4e6fa7674729750d05acc1bf41e (patch) | |
tree | f374693f0fa8f3d446c9952b41954f7c73db2ae2 | |
parent | b6e0985a4c48eb4f5ed115759bc816322942f39c (diff) | |
download | qemu-897dd0ec4fdea4e6fa7674729750d05acc1bf41e.zip qemu-897dd0ec4fdea4e6fa7674729750d05acc1bf41e.tar.gz qemu-897dd0ec4fdea4e6fa7674729750d05acc1bf41e.tar.bz2 |
block: include supported_read_flags into BDS structure
Add the new member supported_read_flags to the BlockDriverState
structure. It will control the flags set for copy-on-read operations.
Make the block generic layer evaluate supported read flags before they
go to a block driver.
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
[vsementsov: use assert instead of abort]
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20201216061703.70908-8-vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
-rw-r--r-- | block/io.c | 10 | ||||
-rw-r--r-- | include/block/block_int.h | 4 |
2 files changed, 12 insertions, 2 deletions
@@ -1453,6 +1453,9 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, if (flags & BDRV_REQ_COPY_ON_READ) { int64_t pnum; + /* The flag BDRV_REQ_COPY_ON_READ has reached its addressee */ + flags &= ~BDRV_REQ_COPY_ON_READ; + ret = bdrv_is_allocated(bs, offset, bytes, &pnum); if (ret < 0) { goto out; @@ -1474,9 +1477,11 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, goto out; } + assert(!(flags & ~bs->supported_read_flags)); + max_bytes = ROUND_UP(MAX(0, total_bytes - offset), align); if (bytes <= max_bytes && bytes <= max_transfer) { - ret = bdrv_driver_preadv(bs, offset, bytes, qiov, qiov_offset, 0); + ret = bdrv_driver_preadv(bs, offset, bytes, qiov, qiov_offset, flags); goto out; } @@ -1489,7 +1494,8 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, ret = bdrv_driver_preadv(bs, offset + bytes - bytes_remaining, num, qiov, - qiov_offset + bytes - bytes_remaining, 0); + qiov_offset + bytes - bytes_remaining, + flags); max_bytes -= num; } else { num = bytes_remaining; diff --git a/include/block/block_int.h b/include/block/block_int.h index f3d0a0e..92d3754 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -881,6 +881,10 @@ struct BlockDriverState { /* I/O Limits */ BlockLimits bl; + /* + * Flags honored during pread + */ + unsigned int supported_read_flags; /* Flags honored during pwrite (so far: BDRV_REQ_FUA, * BDRV_REQ_WRITE_UNCHANGED). * If a driver does not support BDRV_REQ_WRITE_UNCHANGED, those |