From b3f427e4eb27091ca712f6c18e2e63a414dc4ce2 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Mon, 11 Jul 2016 05:33:37 +0200 Subject: [PATCH 4/7] scsi-generic: Merge block max xfer len in INQUIRY response RH-Author: Fam Zheng Message-id: <1468215219-30793-5-git-send-email-famz@redhat.com> Patchwork-id: 71108 O-Subject: [RHEL-7.3 qemu-kvm PATCH 4/6] scsi-generic: Merge block max xfer len in INQUIRY response Bugzilla: 1318199 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: John Snow RH-Acked-by: Paolo Bonzini The rationale is similar to the above mode sense response interception: this is practically the only channel to communicate restraints from elsewhere such as host and block driver. The scsi bus we attach onto can have a larger max xfer len than what is accepted by the host file system (guarding between the host scsi LUN and QEMU), in which case the SG_IO we generate would get -EINVAL. Signed-off-by: Fam Zheng Message-Id: <1464243305-10661-3-git-send-email-famz@redhat.com> Signed-off-by: Paolo Bonzini (cherry picked from commit 063143d5b1fde0fdcbae30bc7d6d14e76fa607d2) Signed-off-by: Miroslav Rezanina Conflicts: hw/scsi/scsi-generic.c We don't have BlockBackend in downstream, use bdrv_get_max_transfer_length() instead. The context is different because we don't have fa0d653b0 (scsi-generic: identify AIO callbacks more clearly). Signed-off-by: Fam Zheng --- hw/scsi/scsi-generic.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 3733d2c..6b0c1fe 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -207,6 +207,17 @@ static void scsi_read_complete(void * opaque, int ret) (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { s->blocksize = ldl_be_p(&r->buf[8]); s->max_lba = ldq_be_p(&r->buf[0]); + } else if (s->type == TYPE_DISK && + r->req.cmd.buf[0] == INQUIRY && + r->req.cmd.buf[2] == 0xb0) { + uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs); + if (max_xfer_len) { + stl_be_p(&r->buf[8], max_xfer_len); + /* Also take care of the opt xfer len. */ + if (ldl_be_p(&r->buf[12]) > max_xfer_len) { + stl_be_p(&r->buf[12], max_xfer_len); + } + } } bdrv_set_guest_block_size(s->conf.bs, s->blocksize); -- 1.8.3.1