@@ -349,7 +349,7 @@ static void adjustTrackOnError(FluxSource& fluxSource, int baseTrack)
349349struct ReadGroupResult
350350{
351351 ReadResult result;
352- std::vector<std::shared_ptr<const Sector>> sectors ;
352+ std::vector<std::shared_ptr<const Sector>> combinedSectors ;
353353};
354354
355355static ReadGroupResult readGroup (const DiskLayout& diskLayout,
@@ -360,6 +360,21 @@ static ReadGroupResult readGroup(const DiskLayout& diskLayout,
360360{
361361 ReadGroupResult rgr = {BAD_AND_CAN_NOT_RETRY};
362362
363+ /* Before doing the read, look to see if we already have the necessary
364+ * sectors. */
365+
366+ {
367+ auto [result, sectors] = combineRecordAndSectors (tracks, decoder, ltl);
368+ rgr.combinedSectors = sectors;
369+ if (result == HAS_NO_BAD_SECTORS)
370+ {
371+ /* We have all necessary sectors, so can stop here. */
372+ rgr.result = GOOD_READ;
373+ if (globalConfig ()->decoder ().skip_unnecessary_tracks ())
374+ return rgr;
375+ }
376+ }
377+
363378 for (unsigned offset = 0 ; offset < ltl->groupSize ;
364379 offset += diskLayout.headWidth )
365380 {
@@ -389,7 +404,7 @@ static ReadGroupResult readGroup(const DiskLayout& diskLayout,
389404 /* Decode what we've got so far. */
390405
391406 auto [result, sectors] = combineRecordAndSectors (tracks, decoder, ltl);
392- rgr.sectors = sectors;
407+ rgr.combinedSectors = sectors;
393408 if (result == HAS_NO_BAD_SECTORS)
394409 {
395410 /* We have all necessary sectors, so can stop here. */
@@ -399,8 +414,8 @@ static ReadGroupResult readGroup(const DiskLayout& diskLayout,
399414 }
400415 else if (fluxSourceIterator.hasNext ())
401416 {
402- /* The flux source claims it can do more reads, so mark this group
403- * as being retryable. */
417+ /* The flux source claims it can do more reads, so mark this
418+ * group as being retryable. */
404419 rgr.result = BAD_AND_CAN_RETRY;
405420 }
406421 }
@@ -634,13 +649,13 @@ void writeRawDiskCommand(const DiskLayout& diskLayout,
634649 diskLayout.logicalLocations );
635650}
636651
637- TracksAndSectors readAndDecodeTrack (const DiskLayout& diskLayout,
652+ void readAndDecodeTrack (const DiskLayout& diskLayout,
638653 FluxSource& fluxSource,
639654 Decoder& decoder,
640- const std::shared_ptr<const LogicalTrackLayout>& ltl)
655+ const std::shared_ptr<const LogicalTrackLayout>& ltl,
656+ std::vector<std::shared_ptr<const Track>>& tracks,
657+ std::vector<std::shared_ptr<const Sector>>& combinedSectors)
641658{
642- TracksAndSectors fas;
643-
644659 if (fluxSource.isHardware ())
645660 measureDiskRotation ();
646661
@@ -649,9 +664,8 @@ TracksAndSectors readAndDecodeTrack(const DiskLayout& diskLayout,
649664 for (;;)
650665 {
651666 auto [result, sectors] = readGroup (
652- diskLayout, fluxSourceIteratorHolder, ltl, fas.tracks , decoder);
653- std::copy (
654- sectors.begin (), sectors.end (), std::back_inserter (fas.sectors ));
667+ diskLayout, fluxSourceIteratorHolder, ltl, tracks, decoder);
668+ combinedSectors = sectors;
655669 if (result == GOOD_READ)
656670 break ;
657671 if (result == BAD_AND_CAN_NOT_RETRY)
@@ -673,8 +687,6 @@ TracksAndSectors readAndDecodeTrack(const DiskLayout& diskLayout,
673687 retriesRemaining--;
674688 }
675689 }
676-
677- return fas;
678690}
679691
680692void readDiskCommand (const DiskLayout& diskLayout,
@@ -687,6 +699,13 @@ void readDiskCommand(const DiskLayout& diskLayout,
687699 outputFluxSinkFactory =
688700 FluxSinkFactory::create (globalConfig ()->decoder ().copy_flux_to ());
689701
702+ std::map<CylinderHead, std::vector<std::shared_ptr<const Track>>>
703+ tracksByLogicalLocation;
704+ for (auto & [ch, track] : disk.tracksByPhysicalLocation )
705+ tracksByLogicalLocation[CylinderHead (track->ltl ->logicalCylinder ,
706+ track->ltl ->logicalHead )]
707+ .push_back (track);
708+
690709 log (BeginOperationLogMessage{" Reading and decoding disk" });
691710 {
692711 std::unique_ptr<FluxSink> outputFluxSink;
@@ -702,13 +721,31 @@ void readDiskCommand(const DiskLayout& diskLayout,
702721
703722 testForEmergencyStop ();
704723
705- auto [trackFluxes, trackSectors] =
706- readAndDecodeTrack (diskLayout, fluxSource, decoder, ltl);
724+ auto & trackFluxes = tracksByLogicalLocation[logicalLocation];
725+ std::vector<std::shared_ptr<const Sector>> trackSectors;
726+ readAndDecodeTrack (diskLayout,
727+ fluxSource,
728+ decoder,
729+ ltl,
730+ trackFluxes,
731+ trackSectors);
732+
733+ /* Replace all tracks on the disk by the new combined set. */
734+
735+ for (const auto & flux : trackFluxes)
736+ disk.tracksByPhysicalLocation .erase (CylinderHead{
737+ flux->ptl ->physicalCylinder , flux->ptl ->physicalHead });
707738 for (const auto & flux : trackFluxes)
708739 disk.tracksByPhysicalLocation .emplace (
709740 CylinderHead{
710741 flux->ptl ->physicalCylinder , flux->ptl ->physicalHead },
711742 flux);
743+
744+ /* Likewise for sectors. */
745+
746+ for (const auto & sector : trackSectors)
747+ disk.sectorsByPhysicalLocation .erase (
748+ sector->physicalLocation .value ());
712749 for (const auto & sector : trackSectors)
713750 disk.sectorsByPhysicalLocation .emplace (
714751 sector->physicalLocation .value (), sector);
0 commit comments