Sfoglia il codice sorgente

Fix data corruption in read prefetch logic (#43)

When a read request was mostly, but not completely, satisfied out of
prefetch buffer, data corruption could occur. This depended on the
specific timing of requests and was quite rare.

Root cause was that the next prefetch started before checking whether
all prefetch data for current request had been written out.
Petteri Aimonen 3 anni fa
parent
commit
1916425deb
1 ha cambiato i file con 8 aggiunte e 1 eliminazioni
  1. 8 1
      src/AzulSCSI_disk.cpp

+ 8 - 1
src/AzulSCSI_disk.cpp

@@ -1025,9 +1025,16 @@ static void diskDataIn()
         g_scsi_prefetch.scsiId = scsiDev.target->cfg->scsiId;
         while (!scsiIsWriteFinished(NULL) && prefetch_sectors > 0)
         {
+            // Check if prefetch buffer is free
+            g_disk_transfer.buffer = g_scsi_prefetch.buffer + g_scsi_prefetch.bytes;
+            if (!scsiIsWriteFinished(g_disk_transfer.buffer) ||
+                !scsiIsWriteFinished(g_disk_transfer.buffer + bytesPerSector - 1))
+            {
+                continue;
+            }
+
             // We still have time, prefetch next sectors in case this SCSI request
             // is part of a longer linear read.
-            g_disk_transfer.buffer = g_scsi_prefetch.buffer + g_scsi_prefetch.bytes;
             g_disk_transfer.bytes_sd = bytesPerSector;
             g_disk_transfer.bytes_scsi = bytesPerSector; // Tell callback not to send to SCSI
             image_config_t &img = *(image_config_t*)scsiDev.target->cfg;