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 --- fs/exfat/exfat_raw.h | 1 + fs/exfat/file.c | 1 + fs/exfat/super.c | 11 ++++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/exfat/exfat_raw.h b/fs/exfat/exfat_raw.h index 4082fa7b8c14..ec70cd35bba0 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 2daf0dbabb24..6fa720e99103 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 83396fd265cd..95d87e2d7717 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)) -- 2.53.0.1.ga224b40d3f.dirty