diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-05 15:48:09 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-05 15:48:09 -0800 |
| commit | e40e023591ff7fa7863cacced9d6452f7805f8cf (patch) | |
| tree | 76c3f651dc724a1e0ecc2673335963212199930b /fs/exfat/balloc.c | |
| parent | 4b6b4321280ea1ea1e101fd39d8664195d18ecb0 (diff) | |
| parent | 51fc7b4ce10ccab8ea5e4876bcdc42cf5202a0ef (diff) | |
Merge tag 'exfat-for-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat updates from Namjae Jeon:
- Fix a remount failure caused by differing process masks by inheriting
the original mount options during the remount process
- Fix a potential divide-by-zero error and system crash in
exfat_allocate_bitmap that occurred when the readahead count was zero
- Add validation for directory cluster bitmap bits to prevent directory
and root cluster from being incorrectly zeroed out on corrupted
images
- Clear the post-EOF page cache when extending a file to prevent stale
mmap data from becoming visible, addressing an generic/363 failure
- Fix a reference count leak in exfat_find by properly releasing the
dentry set in specific error paths
* tag 'exfat-for-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
exfat: fix remount failure in different process environments
exfat: fix divide-by-zero in exfat_allocate_bitmap
exfat: validate the cluster bitmap bits of directory
exfat: zero out post-EOF page cache on file extension
exfat: fix refcount leak in exfat_find
Diffstat (limited to 'fs/exfat/balloc.c')
| -rw-r--r-- | fs/exfat/balloc.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c index 2d2d510f2372..5429041c7eaf 100644 --- a/fs/exfat/balloc.c +++ b/fs/exfat/balloc.c @@ -106,7 +106,7 @@ static int exfat_allocate_bitmap(struct super_block *sb, (PAGE_SHIFT - sb->s_blocksize_bits); for (i = 0; i < sbi->map_sectors; i++) { /* Trigger the next readahead in advance. */ - if (0 == (i % max_ra_count)) { + if (max_ra_count && 0 == (i % max_ra_count)) { blk_start_plug(&plug); for (j = i; j < min(max_ra_count, sbi->map_sectors - i) + i; j++) sb_breadahead(sb, sector + j); @@ -183,11 +183,10 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi) kvfree(sbi->vol_amap); } -int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync) +int exfat_set_bitmap(struct super_block *sb, unsigned int clu, bool sync) { int i, b; unsigned int ent_idx; - struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); if (!is_valid_cluster(sbi, clu)) @@ -202,11 +201,10 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync) return 0; } -int exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) +int exfat_clear_bitmap(struct super_block *sb, unsigned int clu, bool sync) { int i, b; unsigned int ent_idx; - struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); if (!is_valid_cluster(sbi, clu)) @@ -226,6 +224,28 @@ int exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) return 0; } +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 (!sbi->vol_amap) + return true; + + 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; +} + /* * If the value of "clu" is 0, it means cluster 2 which is the first cluster of * the cluster heap. |