[RFC PATCH v1 2/6] exfat: take bitmap_lock at the start of exfat_alloc_cluster()
Chi Zhiling <[email protected]>
| Newsgroups | dev.linux.lists.exfat,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Chi Zhiling <[email protected]> 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 <[email protected]> --- 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