Skip to content

Commit 501470f

Browse files
PoC-deverichelgeson
authored andcommitted
as400: don't let the prefetch cache bypass a Skip Read's mask
scsiDiskStartRead() consults the read-ahead prefetch cache before deciding how to serve a read, and that cache holds sectors from a prior ordinary contiguous read. A Skip Read gathers its sectors per the mask, which skips and reorders relative to a straight LBA run, so serving the linked Read10 from the cache returns contiguous data and silently ignores the mask. The Skip Read branch sits further down the same function, after the cache has already answered. Invalidate the cache when a Skip Read starts in scsiDiskSkip(), so the lookup stays a single unconditional line. Upstream calls this latent because their AS/400 reporters all ran PrefetchBytes=0. That does not carry over: BlueSCSI defaults prefetchBytes to PREFETCH_BUFFER_SIZE (8192), so the path is reachable on a stock bluescsi.ini. Ported from z/main 1a18f841a (ZuluSCSI PR #917). Manual port: BlueSCSI has no scsiDiskPrefetchInvalidate() helper, so this clears g_scsi_prefetch inline the way the rest of the file already does. Upstream's first attempt at this, an #ifdef-wrapped braceless if around the lookup, was rejected in review as a dangling-if hazard and is not what landed. Test plan: skipped, same reason as the preceding commit. Build verified on Ultra.
1 parent 8af62f9 commit 501470f

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

src/BlueSCSI_disk.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,6 +3346,20 @@ static void scsiDiskSkip(uint32_t lba, uint32_t blocks, uint8_t mask_length, uin
33463346
g_disk_transfer.skip_direction = skip_direction;
33473347
g_disk_transfer.skip_position = 0;
33483348

3349+
#ifdef PREFETCH_BUFFER_SIZE
3350+
if (skip_direction == 0xE8)
3351+
{
3352+
// A Skip Read gathers its sectors per the mask, which skips and
3353+
// reorders relative to a straight LBA run. scsiDiskStartRead()
3354+
// consults the prefetch cache unconditionally, and that cache
3355+
// holds sectors from a prior ordinary contiguous read, so the
3356+
// linked Read10 that follows would be served contiguous data and
3357+
// silently bypass the mask. Invalidate it here.
3358+
g_scsi_prefetch.bytes = 0;
3359+
g_scsi_prefetch.sector = 0;
3360+
}
3361+
#endif
3362+
33493363
// Support optional linked command (CDB byte 9 bit 0)
33503364
if (scsiDev.cdb[9] & 1)
33513365
{

0 commit comments

Comments
 (0)