Re: [PATCH v1 2/4] ntfs: fix rollback after MFT bitmap run coalescing
From: liubaolin
Date: Wed Sep 23 2026 - 22:31:00 EST
在 2026/9/24 09:45, Xuewen Wang 写道:
After the direct allocation attempt drops lcnbmp_lock, a concurrent free
can let ntfs_cluster_alloc() return the adjacent cluster. The merged
runlist then extends the existing last run, but rollback assumes a new
run was added. A later metadata failure removes the old mapping and
frees its first cluster.
Record whether the allocated cluster is adjacent before merging the
runlists. On rollback, shorten a coalesced run by one cluster and free
only that cluster; remove the new run for a non-adjacent allocation.
Suggested-by: Baolin Liu <liubaolin@xxxxxxxxxx>
Reviewed-by: Baolin Liu <liubaolin@xxxxxxxxxx>
Signed-off-by: Xuewen Wang <wangxuewen@xxxxxxxxxx>
---
fs/ntfs/mft.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 88bac85d22bc..12666668a80e 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1428,6 +1428,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(struct ntfs_volume *vol)
"Failed to allocate a cluster for the mft bitmap.");
return PTR_ERR(rl2);
}
+ /* The adjacent cluster may have become available while unlocked. */
+ status.added_cluster = rl2->lcn == lcn;
rl = ntfs_runlists_merge(&mftbmp_ni->runlist, rl2, 0, &new_rl_count);
if (IS_ERR(rl)) {
up_write(&mftbmp_ni->runlist.lock);
@@ -1442,8 +1444,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(struct ntfs_volume *vol)
}
mftbmp_ni->runlist.rl = rl;
mftbmp_ni->runlist.count = new_rl_count;
- status.added_run = 1;
- ntfs_debug("Adding one run to mft bitmap.");
+ status.added_run = !status.added_cluster;
+ ntfs_debug("Allocated one cluster for mft bitmap.");
/* Find the last run in the new runlist. */
for (; rl[1].length; rl++)
;
Looks good to me.
Reviewed-by: Baolin Liu <liubaolin@xxxxxxxxxx>