v0.13.45: multipass adaptive probe, NOT_READY retry, progress bytes_bad_total
- Adaptive probe algorithm in Disc::copy skip_on_error mode: after 4 consecutive errors, probe 1 sector at 256x batch (8 MB) ahead. If good, zero-fill gap, mark NonTrimmed, jump. Clears bad zones in seconds instead of hours. - NOT_READY sense key (0x02) now retries up to 3x with 3s pause before marking NonTrimmed. BU40N returns NOT READY for bad sectors, not MEDIUM ERROR. - PassProgress struct gains bytes_bad_total field for consumer-side bad/retryable byte counts. - Mapfile header version string fix: no longer duplicates 'libfreemkv v' prefix on each write. - Structured sense_key/asc/ascq logging in copy error path.
This commit is contained in:
@@ -26,6 +26,36 @@ The library contains ZERO user-facing English text. All errors use numeric codes
|
||||
- `--raw` only skips decryption. Init/probe/speed still run.
|
||||
- Each function does one thing. One runner orchestrates the sequence.
|
||||
|
||||
## macOS IOKit transport
|
||||
|
||||
The macOS SCSI transport uses exclusive IOKit access, not hybrid MMC+pread.
|
||||
|
||||
- **C shim** (`src/scsi/macos_shim.c`): `diskutil unmountDisk force` → find IOBDServices via `IOServiceMatching` → MMCDeviceInterface → SCSITaskDeviceInterface → `ObtainExclusiveAccess` → raw CDB dispatch via `CreateSCSITask` + `ExecuteTaskSync`.
|
||||
- **Build** (`build.rs`): compiles shim via `cc` into static lib, linked by Cargo. NOT the `cc` crate (produces object code that breaks IOKit exclusive access).
|
||||
- **Rust** (`src/scsi/macos.rs`): three FFI calls (`shim_open_exclusive`, `shim_close`, `shim_execute`). All CDBs go through single path — 1:1 with Linux SG_IO.
|
||||
- **Key**: must find IOBDServices directly (not walk up from IOMedia). Must unmount before exclusive access. Must release service immediately after creating plugin.
|
||||
- **IOBDServices parent chain**: IOMedia → IOBDBlockStorageDriver → IOBDServices → IOSCSIPeripheralDeviceType05. The block storage driver holds exclusive unless unmounted.
|
||||
- **Test disc**: DUNE_PART_TWO UHD, `/dev/disk6`, 41288704 sectors.
|
||||
|
||||
## Bad-sector handling (BU40N + Initio INIC-1618L)
|
||||
|
||||
Three failure modes on this USB bridge:
|
||||
1. **NOT READY** (sense_key=2, ASC=0x04, ASCQ=0x3E) — most common on BU40N for bad sectors. Pause 3s, retry up to 3x, then mark NonTrimmed.
|
||||
2. **Transport failure** (status=0xFF) — bridge crash, auto-recovers ~15s. Aborts copy.
|
||||
3. **INCOMPATIBLE FORMAT** (ASC=0x30) wedge — ALL sectors fail, requires power cycle.
|
||||
|
||||
### Adaptive probe algorithm (Pass 1 sweep)
|
||||
|
||||
When `skip_on_error=true` (multipass mode):
|
||||
- Read each ECC block sequentially. On success, reset consecutive error counter.
|
||||
- On error: zero-fill, mark NonTrimmed, increment consecutive error counter.
|
||||
- After 4 consecutive errors: **probe** 1 sector at 256×batch (8 MB) ahead.
|
||||
- Probe succeeds: zero-fill the gap, mark it NonTrimmed, jump to probed position.
|
||||
- Probe fails: stay put, accumulate 4 more errors, probe again.
|
||||
- Only transport failures (bridge crash) abort the pass.
|
||||
|
||||
Design rationale: consecutive errors (not total) so isolated scattered bad blocks don't trigger probes. The 8 MB probe distance clears typical ~30 MB bad zones in 2-3 probes. Gaps are zero-filled and marked NonTrimmed for patch passes to recover later.
|
||||
|
||||
## Public repo rules
|
||||
|
||||
- **No internal docs.** Audit reports, test plans, roadmaps, TODOs go in freemkv-private, never here.
|
||||
|
||||
Reference in New Issue
Block a user