]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
exfat: fix s_maxbytes
authorDavid Timber <dxdt@dev.snart.me>
Mon, 16 Mar 2026 21:41:37 +0000 (06:41 +0900)
committerNamjae Jeon <linkinjeon@kernel.org>
Tue, 31 Mar 2026 14:01:07 +0000 (23:01 +0900)
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 <dxdt@dev.snart.me>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/exfat/exfat_raw.h
fs/exfat/file.c
fs/exfat/super.c

index 4082fa7b8c1426ab1eb748ea8297063512043ba9..ec70cd35bba0c58654c454c16aea1c83e3c42ee3 100644 (file)
@@ -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
index 2daf0dbabb24d3f4ac1f68c629c29f7e5ca289ec..6fa720e99103c7035ae784e3cac1e1193b46aece 100644 (file)
@@ -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)
index 83396fd265cdad4a8e4ffabc8593f9cfb51e9cb4..95d87e2d7717f7b3917bf9bcb31f99359aaf8e45 100644 (file)
@@ -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))