From: David Timber Date: Mon, 16 Mar 2026 21:41:37 +0000 (+0900) Subject: exfat: fix s_maxbytes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4129a3a2751cba8511cee5d13145223662a8e019;p=thirdparty%2Fkernel%2Flinux.git exfat: fix s_maxbytes With fallocate support, xfstest unit generic/213 fails with QA output created by 213 We should get: fallocate: No space left on device Strangely, xfs_io sometimes says "Success" when something went wrong -fallocate: No space left on device +fallocate: File too large because sb->s_maxbytes is set to the volume size. To be in line with other non-extent-based filesystems, set to max volume size possible with the cluster size of the volume. Signed-off-by: David Timber Signed-off-by: Namjae Jeon --- diff --git a/fs/exfat/exfat_raw.h b/fs/exfat/exfat_raw.h index 4082fa7b8c142..ec70cd35bba0c 100644 --- a/fs/exfat/exfat_raw.h +++ b/fs/exfat/exfat_raw.h @@ -25,6 +25,7 @@ #define EXFAT_FIRST_CLUSTER 2 #define EXFAT_DATA_CLUSTER_COUNT(sbi) \ ((sbi)->num_clusters - EXFAT_RESERVED_CLUSTERS) +#define EXFAT_MAX_NUM_CLUSTER (0xFFFFFFF5) /* AllocationPossible and NoFatChain field in GeneralSecondaryFlags Field */ #define ALLOC_POSSIBLE 0x01 diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 2daf0dbabb24d..6fa720e99103c 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -34,6 +34,7 @@ static int exfat_cont_expand(struct inode *inode, loff_t size) return ret; num_clusters = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi); + /* integer overflow is already checked in inode_newsize_ok(). */ new_num_clusters = EXFAT_B_TO_CLU_ROUND_UP(size, sbi); if (new_num_clusters == num_clusters) diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 83396fd265cda..95d87e2d7717f 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -531,9 +531,14 @@ static int exfat_read_boot_sector(struct super_block *sb) if (sbi->vol_flags & MEDIA_FAILURE) exfat_warn(sb, "Medium has reported failures. Some data may be lost."); - /* exFAT file size is limited by a disk volume size */ - sb->s_maxbytes = (u64)(sbi->num_clusters - EXFAT_RESERVED_CLUSTERS) << - sbi->cluster_size_bits; + /* + * Set to the max possible volume size for this volume's cluster size so + * that any integer overflow from bytes to cluster size conversion is + * checked in inode_newsize_ok(). Clamped to MAX_LFS_FILESIZE for 32-bit + * machines. + */ + sb->s_maxbytes = min(MAX_LFS_FILESIZE, + EXFAT_CLU_TO_B((loff_t)EXFAT_MAX_NUM_CLUSTER, sbi)); /* check logical sector size */ if (exfat_calibrate_blocksize(sb, 1 << p_boot->sect_size_bits))