diff options
| author | Zhu Tianhao <zhutianhao75@hotmail.com> | 2026-09-08 05:41:00 +0900 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-09-13 11:41:58 +0900 |
| commit | 229e8188307b9724cc676a49e9600c4acd24b571 (patch) | |
| tree | e309b8ab681aff9bd642c45acedc49d41e2ddfd7 /tools/perf/scripts/python/bin/stackcollapse-record | |
| parent | 0c32a42fd96a0e7c06c8a648a6dd8f1ec0bf643b (diff) | |
| download | linux-next-229e8188307b9724cc676a49e9600c4acd24b571.tar.gz linux-next-229e8188307b9724cc676a49e9600c4acd24b571.zip | |
ntfs: fix $MFTMirr write offset when it spans multiple folios
When commit 115380f9a2f9 ("ntfs: update mft operations") refactored the
MFT code to use folios, it assumed $MFTMirr is allocated contiguously,
which is indeed what mkfs arranges. However, the folio rewrite kept a
leftover from the old buffer-head/runlist based implementation:
vol->cluster_size_mask is still applied to the mirror write offset.
In fact it is no longer needed -- and in some configurations it is
actively wrong.
The bug triggers whenever the four mirror records do not fit in a
single folio, i.e. when mft_record_size exceeds PAGE_SIZE / 4 (for
example mft_record_size > 1KiB on 4KiB pages).
For example, on the built-in 4Kn SSD (Apple SSD AP0256J) of a
MacBookPro14,1 with 4096-byte MFT records, mirror record 3 is still
written to the location of record 0. $MFTMirr therefore gets out of
sync with $MFT and the following warning is printed on remount:
ntfs: (device nvme0n1p3): check_mft_mirror(): $MFT and $MFTMirr
record 0 do not match. Run chkdsk.
Fix it by always adding the folio offset (folio->index << PAGE_SHIFT)
to the base LCN address instead of applying the cluster_size_mask
truncation. This is the standard file-offset calculation and is
correct for every combination of cluster size, page size and MFT
record size, provided $MFTMirr data is contiguous from mftmirr_lcn
(which mkfs always arranges).
Tested on the volume above: before the change mirror records 1-3 are
all written to record 0's sector; after the change the write-back
probe reports:
ntfs: NTFSDBG pre mft_no=0x3 folio_idx=0x3 ofs=0x0 mftmirr_lcn=0x2540c5 clu_bits=12 rec_bits=12 PAGE_SHIFT=12 sect=0x12a0640
ntfs: NTFSDBG pre mft_no=0x0 folio_idx=0x0 ofs=0x0 mftmirr_lcn=0x2540c5 clu_bits=12 rec_bits=12 PAGE_SHIFT=12 sect=0x12a0628
which matches the expected sectors computed as:
(NTFS_CLU_TO_B(mftmirr_lcn) + (folio->index << PAGE_SHIFT)) >> SECTOR_SHIFT
record 0: (0x2540c5 << 12) + 0x0000 = 0x2540c5000 >> 9 = 0x12a0628
record 3: (0x2540c5 << 12) + 0x3000 = 0x2540c8000 >> 9 = 0x12a0640
A 13 MB file write succeeds on this volume and the file is byte-for-byte
identical after a umount/mount cycle.
Fixes: 115380f9a2f9 ("ntfs: update mft operations")
Assisted-by: UOS-AI
Assisted-by: CodeBuddy:Hy4 preview
Signed-off-by: Zhu Tianhao <zhutianhao75@hotmail.com>
Reviewed-by: Baolin Liu <liubaolin@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Diffstat (limited to 'tools/perf/scripts/python/bin/stackcollapse-record')
0 files changed, 0 insertions, 0 deletions
