Просмотр исходного кода

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 лет назад
Родитель
Сommit
1916425deb
1 измененных файлов с 8 добавлено и 1 удалено
  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;