Skip to content

Commit 36c7276

Browse files
zhanxusheng1024-osaalexandrovich
authored andcommitted
fs/ntfs3: fix wrong LCN in run_remove_range() when splitting a run
When run_remove_range() removes a middle portion of a non-sparse run, it splits the run into head and tail parts. The tail is inserted via run_add_entry() but uses the original r->lcn as its starting LCN instead of advancing it by the split offset. For example, removing VCN range [10, 20) from a run {vcn=0, lcn=100, len=30} should produce: {vcn=0, lcn=100, len=10} (head) {vcn=20, lcn=120, len=10} (tail, lcn advanced by 20) But the current code produces: {vcn=0, lcn=100, len=10} {vcn=20, lcn=100, len=10} (wrong: points to same physical clusters) This creates overlapping physical mappings in the in-memory run tree, which can corrupt cluster allocation decisions and lead to data corruption. The correct pattern is already used in run_insert_range(): CLST lcn2 = r->lcn == SPARSE_LCN ? SPARSE_LCN : (r->lcn + len1); Apply the same logic in run_remove_range(). Fixes: 10d7c95 ("fs/ntfs3: add delayed-allocation (delalloc) support") Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
1 parent 57382ec commit 36c7276

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

fs/ntfs3/run.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1297,9 +1297,12 @@ bool run_remove_range(struct runs_tree *run, CLST vcn, CLST len, CLST *done)
12971297

12981298
if (r_end > end) {
12991299
/* Remove a middle part, split. */
1300+
CLST tail_lcn = r->lcn == SPARSE_LCN ?
1301+
SPARSE_LCN : (r->lcn + (end - r->vcn));
1302+
13001303
*done += len;
13011304
r->len = d;
1302-
return run_add_entry(run, end, r->lcn, r_end - end,
1305+
return run_add_entry(run, end, tail_lcn, r_end - end,
13031306
false);
13041307
}
13051308
/* Remove tail of run .*/

0 commit comments

Comments
 (0)