[RFC PATCH v1 2/6] exfat: take bitmap_lock at the start of exfat_alloc_cluster()
From: Chi Zhiling
Date: Fri Aug 21 2026 - 06:49:08 EST
From: Chi Zhiling <chizhiling@xxxxxxxxxx>
Acquire sbi->bitmap_lock at the top of exfat_alloc_cluster() so the
used_clusters/clu_srch_ptr validation and updates are covered by the
lock, removing a window where the early checks raced with concurrent
allocations.
Signed-off-by: Chi Zhiling <chizhiling@xxxxxxxxxx>
---
fs/exfat/fatent.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c
index a8b11e2ce43f..2db959669563 100644
--- a/fs/exfat/fatent.c
+++ b/fs/exfat/fatent.c
@@ -427,19 +427,22 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
struct super_block *sb = inode->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
+ mutex_lock(&sbi->bitmap_lock);
+
total_cnt = EXFAT_DATA_CLUSTER_COUNT(sbi);
if (unlikely(total_cnt < sbi->used_clusters)) {
exfat_fs_error_ratelimit(sb,
"%s: invalid used clusters(t:%u,u:%u)\n",
__func__, total_cnt, sbi->used_clusters);
- return -EIO;
+ ret = -EIO;
+ goto unlock;
}
- if (num_alloc > total_cnt - sbi->used_clusters)
- return -ENOSPC;
-
- mutex_lock(&sbi->bitmap_lock);
+ if (num_alloc > total_cnt - sbi->used_clusters) {
+ ret = -ENOSPC;
+ goto unlock;
+ }
hint_clu = p_chain->dir;
/* find new cluster */
@@ -516,8 +519,8 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
done:
sbi->clu_srch_ptr = hint_clu;
sbi->used_clusters += p_chain->size;
- mutex_unlock(&sbi->bitmap_lock);
- return 0;
+ ret = 0;
+ goto unlock;
}
hint_clu = new_clu + 1;
--
2.53.0