Decision to revisit, not a bug
io::parser::parse_record_to_fragment (plus fragment_extension::parse_extension_to_fragment, ~680 lines) is #[deprecated] and has zero callers in the workspace — only the two re-exports (io.rs:45, io/parser/mod.rs:16) and tests. The live parsers are io::parser::unified::process_record (bulk load) and parse::direct_index::parse_record_to_index (USN incremental).
Deleting it was considered and deliberately rejected for now:
uffs-forensics is a planned in-repo consumer, and carving partial/fragmented records is squarely its remit. Deleting hard-won untrusted-byte parsing and rebuilding it later, worse, is the bad trade. Correct-but-dormant beats deleted-and-rewritten.
uffs-mft is consumable from git by third parties. #[deprecated] is the right signal; the semver-correct path is deprecate then remove in a breaking release, with its own release note — not a silent pub removal riding along in an unrelated PR.
- Confirmed
uffs-products does not use it: zero hits for parse_record_to_fragment, MftIndexFragment, fragment_extension, merge_fragments.
Revisit criteria
Around 2027-01, or once uffs-forensics has shipped — whichever is first:
- If
uffs-forensics shipped and does not use it, and it is still callerless: remove it in a breaking release, with a release note. The argument is then a fact rather than a guess.
- If
uffs-forensics (or any consumer) does use it: drop the #[deprecated], give it real coverage, and treat it as supported.
Context
Found while adding the NTFS 3.0+ $SI fields to ExtendedStandardInfo. Two related fixes already landed and are not blocked on this decision:
fix(mft): stop zeroing usn/security_id/owner_id in the fragment parser — the path hand-rolled a 36-byte NTFS 1.2 $STANDARD_INFORMATION read regardless of the record's real $SI size, silently zeroing those three fields on every modern volume. Now routed through the shared, fuzz-hardened parse_standard_info_full, with a regression pin.
- The stale
#[expect(clippy::too_many_lines, reason = "...performance-critical hot path")] reason string, false since the fragment-merge rewrite, now states the real status. A reason-string that is actively false is worse than none: the next reader treats a dead function as load-bearing, which is how this survived.
Decision to revisit, not a bug
io::parser::parse_record_to_fragment(plusfragment_extension::parse_extension_to_fragment, ~680 lines) is#[deprecated]and has zero callers in the workspace — only the two re-exports (io.rs:45,io/parser/mod.rs:16) and tests. The live parsers areio::parser::unified::process_record(bulk load) andparse::direct_index::parse_record_to_index(USN incremental).Deleting it was considered and deliberately rejected for now:
uffs-forensicsis a planned in-repo consumer, and carving partial/fragmented records is squarely its remit. Deleting hard-won untrusted-byte parsing and rebuilding it later, worse, is the bad trade. Correct-but-dormant beats deleted-and-rewritten.uffs-mftis consumable from git by third parties.#[deprecated]is the right signal; the semver-correct path is deprecate then remove in a breaking release, with its own release note — not a silentpubremoval riding along in an unrelated PR.uffs-productsdoes not use it: zero hits forparse_record_to_fragment,MftIndexFragment,fragment_extension,merge_fragments.Revisit criteria
Around 2027-01, or once
uffs-forensicshas shipped — whichever is first:uffs-forensicsshipped and does not use it, and it is still callerless: remove it in a breaking release, with a release note. The argument is then a fact rather than a guess.uffs-forensics(or any consumer) does use it: drop the#[deprecated], give it real coverage, and treat it as supported.Context
Found while adding the NTFS 3.0+
$SIfields toExtendedStandardInfo. Two related fixes already landed and are not blocked on this decision:fix(mft): stop zeroing usn/security_id/owner_id in the fragment parser— the path hand-rolled a 36-byte NTFS 1.2$STANDARD_INFORMATIONread regardless of the record's real$SIsize, silently zeroing those three fields on every modern volume. Now routed through the shared, fuzz-hardenedparse_standard_info_full, with a regression pin.#[expect(clippy::too_many_lines, reason = "...performance-critical hot path")]reason string, false since the fragment-merge rewrite, now states the real status. A reason-string that is actively false is worse than none: the next reader treats a dead function as load-bearing, which is how this survived.