summaryrefslogtreecommitdiff
path: root/block/raw_bsd.c
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-07-15 12:32:00 -0600
committerStefan Hajnoczi <stefanha@redhat.com>2016-07-20 14:11:54 +0100
commit8a39b4d6e2926a536027f7ffbc28a3ed2e5d32b0 (patch)
tree2c962ae32887d9635238f61e0de1e6732d695fb6 /block/raw_bsd.c
parent1a62d0accdf85fbeac149018ee8d1728e754de73 (diff)
downloadqemu-8a39b4d6e2926a536027f7ffbc28a3ed2e5d32b0.zip
raw_bsd: Don't advertise flags not supported by protocol layer
The raw format layer supports all flags via passthrough - but it only makes sense to pass through flags that the lower layer actually supports. The next patch gives stronger reasoning for why this is correct. At the moment, the raw format layer ignores the max_transfer limit of its protocol layer, and an attempt to do the qemu-io 'w -f 0 40m' to an NBD server that lacks FUA will pass the entire 40m request to the NBD driver, which then fragments the request itself into a 32m write, 8m write, and flush. But once the block layer starts honoring limits and fragmenting packets, the raw driver will hand the NBD driver two separate requests; if both requests have BDRV_REQ_FUA set, then this would result in a 32m write, flush, 8m write, and second flush. By having the raw layer no longer advertise FUA support when the protocol layer lacks it, we are back to a single flush at the block layer for the overall 40m request. Note that 'w -f -z 0 40m' does not currently exhibit the same problem, because there, the fragmentation does not occur until at the NBD layer (the raw layer has .bdrv_co_pwrite_zeroes, and the NBD layer doesn't advertise max_pwrite_zeroes to constrain things at the raw layer) - but the problem is latent and we would again have too many flushes without this patch once the NBD layer implements support for the new NBD_CMD_WRITE_ZEROES command, if it sets max_pwrite_zeroes to the same 32m limit as recommended by the NBD protocol. Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 1468607524-19021-3-git-send-email-eblake@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/raw_bsd.c')
-rw-r--r--block/raw_bsd.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 5f9dd299a6..d7674132f2 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -192,8 +192,10 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
bs->sg = bs->file->bs->sg;
- bs->supported_write_flags = BDRV_REQ_FUA;
- bs->supported_zero_flags = BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP;
+ bs->supported_write_flags = BDRV_REQ_FUA &
+ bs->file->bs->supported_write_flags;
+ bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
+ bs->file->bs->supported_zero_flags;
if (bs->probed && !bdrv_is_read_only(bs)) {
fprintf(stderr,