From d581eb7ca4b58649ade5fb7570ecf6b4b9a41879 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 2 Apr 2014 13:24:23 +0200 Subject: [PATCH 1/4] scsi-bus: remove bogus assertion This assertion is invalid, because get_sg_list can return an empty sg-list even for commands that transfer no data (such as SYNCHRONIZE CACHE). Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index eaad925cbb..ae921a6a75 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -101,7 +101,6 @@ static void scsi_dma_restart_bh(void *opaque) scsi_req_continue(req); break; case SCSI_XFER_NONE: - assert(!req->sg); scsi_req_dequeue(req); scsi_req_enqueue(req); break; From 27898a5daa4c6d28adb32b401a011d7198494482 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 2 Apr 2014 12:12:50 +0200 Subject: [PATCH 2/4] iscsi: recognize "invalid field" ASCQ from WRITE SAME command Some targets may return "invalid field" as the ASCQ from WRITE SAME if they support the command only without the UNMAP field. Recognize that, and return ENOTSUP just like for "invalid operation code". Reviewed-by: Peter Lieven Signed-off-by: Paolo Bonzini --- block/iscsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/iscsi.c b/block/iscsi.c index b490e98c05..2f96a8e037 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -838,7 +838,8 @@ retry: if (iTask.status == SCSI_STATUS_CHECK_CONDITION && iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST && - iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + (iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE || + iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB)) { /* WRITE SAME is not supported by the target */ iscsilun->has_write_same = false; scsi_free_scsi_task(iTask.task); From b2f9c08a4f11f16ec101e95feab8e71d7cfcfee9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 2 Apr 2014 15:04:41 +0200 Subject: [PATCH 3/4] iscsi: ignore flushes on scsi-generic devices Non-block SCSI devices do not support flushing, but we may still send them requests via bdrv_flush_all. Just ignore them. Reviewed-by: Peter Lieven Signed-off-by: Paolo Bonzini --- block/iscsi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/block/iscsi.c b/block/iscsi.c index 2f96a8e037..e68aa0ffde 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -417,6 +417,10 @@ static int coroutine_fn iscsi_co_flush(BlockDriverState *bs) IscsiLun *iscsilun = bs->opaque; struct IscsiTask iTask; + if (bs->sg) { + return 0; + } + iscsi_co_init_iscsitask(iscsilun, &iTask); retry: From c97ca29db0a68deb281a901f535cec5ea4862244 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 2 Apr 2014 15:30:29 +0200 Subject: [PATCH 4/4] iscsi: always query max WRITE SAME length Max WRITE SAME length is also used when the UNMAP bit is zero, so it should be queried even if LBPWS=0. Same for the optimal transfer length. However, the write_zeroes_alignment only matters for UNMAP=1 so we still restrict it to LBPWS=1. Reviewed-by: Peter Lieven Signed-off-by: Paolo Bonzini --- block/iscsi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index e68aa0ffde..21c18a39dc 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1335,18 +1335,20 @@ static int iscsi_refresh_limits(BlockDriverState *bs) /* We don't actually refresh here, but just return data queried in * iscsi_open(): iscsi targets don't change their limits. */ - if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) { + if (iscsilun->lbp.lbpu) { if (iscsilun->bl.max_unmap < 0xffffffff) { bs->bl.max_discard = sector_lun2qemu(iscsilun->bl.max_unmap, iscsilun); } bs->bl.discard_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun); + } - if (iscsilun->bl.max_ws_len < 0xffffffff) { - bs->bl.max_write_zeroes = sector_lun2qemu(iscsilun->bl.max_ws_len, - iscsilun); - } + if (iscsilun->bl.max_ws_len < 0xffffffff) { + bs->bl.max_write_zeroes = sector_lun2qemu(iscsilun->bl.max_ws_len, + iscsilun); + } + if (iscsilun->lbp.lbpws) { bs->bl.write_zeroes_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun); }