Patchwork [v4,18/18] scsi-block: always use scsi_generic_ops for cache != none

login
register
mail settings
Submitter Paolo Bonzini
Date Feb. 22, 2012, 2:33 p.m.
Message ID <1329921236-23461-19-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/142498/
State New
Headers show

Comments

Paolo Bonzini - Feb. 22, 2012, 2:33 p.m.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi-disk.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

Patch

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index ec8e7cb..4101a59 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1754,6 +1754,15 @@  static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
     case WRITE_VERIFY_10:
     case WRITE_VERIFY_12:
     case WRITE_VERIFY_16:
+        /* If we are not using O_DIRECT, we might read stale data from the
+         * host cache if writes were made using other commands than these
+         * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
+         * O_DIRECT everything must go through SG_IO.
+         */
+        if (!(s->qdev.conf.bs->open_flags & BDRV_O_NOCACHE)) {
+            break;
+        }
+
         /* 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
@@ -1764,10 +1773,11 @@  static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
          * 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);
-        }
+        if (s->qdev.type == TYPE_ROM) {
+            break;
+        }
+        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,