diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c index 2d2d510f2372..e6d5b9cb56d6 100644 --- a/fs/exfat/balloc.c +++ b/fs/exfat/balloc.c @@ -24,6 +24,25 @@ #error "BITS_PER_LONG not 32 or 64" #endif +bool exfat_test_bitmap(struct super_block *sb, unsigned int clu) +{ + int i, b; + unsigned int ent_idx; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + if (!is_valid_cluster(sbi, clu)) + return false; + + ent_idx = CLUSTER_TO_BITMAP_ENT(clu); + i = BITMAP_OFFSET_SECTOR_INDEX(sb, ent_idx); + b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx); + + if (!test_bit_le(b, sbi->vol_amap[i]->b_data)) + return false; + + return true; +} + /* * Allocation Bitmap Management Functions */ diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 38210fb6901c..6a317917506c 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -450,6 +450,7 @@ int exfat_count_num_clusters(struct super_block *sb, struct exfat_chain *p_chain, unsigned int *ret_count); /* balloc.c */ +bool exfat_test_bitmap(struct super_block *sb, unsigned int clu); int exfat_load_bitmap(struct super_block *sb); void exfat_free_bitmap(struct exfat_sb_info *sbi); int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync); diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 7f9592856bf7..ce05dc604e13 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -626,6 +626,12 @@ static int __exfat_fill_super(struct super_block *sb, goto free_bh; } + if (!exfat_test_bitmap(sb, sbi->root_dir)) { + exfat_err(sb, "failed to test root cluster bit"); + ret = -EIO; + goto free_alloc_bitmap; + } + ret = exfat_count_used_clusters(sb, &sbi->used_clusters); if (ret) { exfat_err(sb, "failed to scan clusters");