From: Zhan Xusheng Date: Fri, 8 May 2026 09:52:45 +0000 (+0800) Subject: fs/ntfs3: fix wrong LCN in run_remove_range() when splitting a run X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=36c7276816ed4266c155b71b1fa747b2785f23f7;p=thirdparty%2Fkernel%2Flinux.git 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: 10d7c95af043 ("fs/ntfs3: add delayed-allocation (delalloc) support") Signed-off-by: Zhan Xusheng Signed-off-by: Konstantin Komarov --- diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c index 19aa044fd1fc..ad7db67514ef 100644 --- a/fs/ntfs3/run.c +++ b/fs/ntfs3/run.c @@ -1297,9 +1297,12 @@ bool run_remove_range(struct runs_tree *run, CLST vcn, CLST len, CLST *done) if (r_end > end) { /* Remove a middle part, split. */ + CLST tail_lcn = r->lcn == SPARSE_LCN ? + SPARSE_LCN : (r->lcn + (end - r->vcn)); + *done += len; r->len = d; - return run_add_entry(run, end, r->lcn, r_end - end, + return run_add_entry(run, end, tail_lcn, r_end - end, false); } /* Remove tail of run .*/