You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix for extension record `$FILE_NAME` merging bug that caused 73,721 missing paths on D-Drive.
6
+
7
+
## What Failed
8
+
9
+
**Root Cause**: When a directory or file has so many attributes that the `$FILE_NAME` attribute is pushed to an extension record (not in the base record), the Rust MFT parser was not properly merging the name into the base record.
10
+
11
+
The bug was in two functions in `crates/uffs-mft/src/io.rs`:
12
+
1.`parse_extension_to_index`
13
+
2.`parse_extension_to_fragment`
14
+
15
+
Both functions were:
16
+
- Adding extension names to the `links` buffer
17
+
- Chaining them to `record.first_name.next_entry`
18
+
19
+
But they were **NOT** checking if `record.first_name` itself was empty! When the base record had no `$FILE_NAME` attribute, `first_name` remained empty, and the chained names were never used for path resolution.
20
+
21
+
## The Fix
22
+
23
+
When processing extension records with `$FILE_NAME` attributes:
24
+
25
+
1.**Check if base record has no name**: `!record.first_name.name.is_valid()`
26
+
2.**If empty**: Copy the first extension name **directly into `first_name`** (not just chain it)
27
+
3.**If not empty**: Chain extension names as additional hard links (original behavior)
28
+
29
+
This matches the C++ behavior in `ntfs_index.hpp` lines 559-567.
30
+
31
+
## Files Changed
32
+
33
+
-`crates/uffs-mft/src/io.rs`: Fixed `parse_extension_to_index` and `parse_extension_to_fragment`
34
+
35
+
## Impact
36
+
37
+
- Fixes 73,721 missing paths on D-Drive (1.0% of total)
38
+
- Caused by ~60 directories and ~341 files having `$FILE_NAME` only in extension records
39
+
- All 73 uffs-mft tests pass
40
+
- Build succeeds for uffs-mft and uffs-cli
41
+
42
+
## CI Pipeline Status
43
+
44
+
### Run 1 - Failed (Clippy errors in test code)
45
+
-`$FILE_NAME` should be `` `$FILE_NAME` `` in doc comments
46
+
-`"test_directory".to_string()` should be `"test_directory".to_owned()`
47
+
-`merged` is too similar to `merger` - renamed to `result` and `record_merger`
48
+
49
+
### Run 2 - Failed (Borrow checker error in Windows cross-compile)
50
+
```
51
+
error[E0502]: cannot borrow `*fragment` as mutable because it is also borrowed as immutable
52
+
--> crates/uffs-mft/src/io.rs:1719:26
53
+
```
54
+
**Fix**: Copy values from `fragment.links[...]` to local variables before calling `fragment.get_or_create()`.
Copy file name to clipboardExpand all lines: README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ Traditional file search tools (including `os.walk`, `FindFirstFile`, etc.) work
21
21
22
22
**UFFS reads the MFT directly** - once - and queries it in memory using Polars DataFrames. This is like reading the entire phonebook once instead of looking up each name individually.
23
23
24
-
### Benchmark Results (v0.2.143)
24
+
### Benchmark Results (v0.2.144)
25
25
26
26
| Drive Type | Records | Time | Throughput |
27
27
|------------|---------|------|------------|
@@ -33,7 +33,7 @@ Traditional file search tools (including `os.walk`, `FindFirstFile`, etc.) work
33
33
34
34
| Comparison | Records | Time | Notes |
35
35
|------------|---------|------|-------|
36
-
|**UFFS v0.2.143**|**18.7 Million**|**~142 seconds**| All disks, fast mode |
36
+
|**UFFS v0.2.144**|**18.7 Million**|**~142 seconds**| All disks, fast mode |
0 commit comments