From 91a3c595c43fe12c40225470a5dafed1ad599688 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Feb 2012 14:12:34 +0100 Subject: [PATCH 078/109] scsi-block: always use SG_IO for MMC devices RH-Author: Paolo Bonzini Message-id: <1329919979-20948-78-git-send-email-pbonzini@redhat.com> Patchwork-id: 37556 O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 077/102] scsi-block: always use SG_IO for MMC devices Bugzilla: 782029 RH-Acked-by: Laszlo Ersek RH-Acked-by: Orit Wasserman RH-Acked-by: Gerd Hoffmann CD burning messes up the state of the host page cache and host block device. Just pass all operations down to the device, even though that might have slightly worse performance. Everything else just is not reliable in combination with burning. Reported-by: Thomas Schmitt Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf (cherry picked from 33ebad12637a2e1503247fbb4d2960eaaff084ee) --- hw/scsi-disk.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) Signed-off-by: Michal Novotny --- hw/scsi-disk.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index f93aad2..7aaec37 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1698,8 +1698,20 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag, case WRITE_VERIFY_10: case WRITE_VERIFY_12: case WRITE_VERIFY_16: - return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, - hba_private); + /* MMC writing cannot be done via pread/pwrite, because it sometimes + * involves writing beyond the maximum LBA or to negative LBA (lead-in). + * And once you do these writes, reading from the block device is + * unreliable, too. It is even possible that reads deliver random data + * from the host page cache (this is probably a Linux bug). + * + * We might use scsi_disk_reqops as long as no writing commands are + * seen, but performance usually isn't paramount on optical media. So, + * just make scsi-block operate the same as scsi-generic for them. + */ + if (s->qdev.type != TYPE_ROM) { + return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, + hba_private); + } } return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun, -- 1.7.7.6