From: Christophe Vu-Brugier <christophe.vu-brugier@xxxxxxxxxxx> In exfat_truncate(), the computation of inode->i_blocks is wrong if the file is larger than 4 GiB because a 32-bit variable is used as a mask. This is fixed by casting the variable to loff_t which is 64-bit. Also fix the same computation in exfat_read_root(). This commit is similar to Sungjong Seo's fix in exfat_fill_inode() last month: commit 0c336d6e33f4 ("exfat: fix incorrect loading of i_blocks for large files") Signed-off-by: Christophe Vu-Brugier <christophe.vu-brugier@xxxxxxxxxxx> --- fs/exfat/file.c | 2 +- fs/exfat/super.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 6af0191b648f..109ade79da33 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -252,7 +252,7 @@ void exfat_truncate(struct inode *inode, loff_t size) mark_inode_dirty(inode); inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) & - ~(sbi->cluster_size - 1)) >> inode->i_blkbits; + ~((loff_t)sbi->cluster_size - 1)) >> inode->i_blkbits; write_size: aligned_size = i_size_read(inode); if (aligned_size & (blocksize - 1)) { diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 5539ffc20d16..ea16769380c6 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -364,8 +364,8 @@ static int exfat_read_root(struct inode *inode) inode->i_op = &exfat_dir_inode_operations; inode->i_fop = &exfat_dir_operations; - inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) - & ~(sbi->cluster_size - 1)) >> inode->i_blkbits; + inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) & + ~((loff_t)sbi->cluster_size - 1)) >> inode->i_blkbits; EXFAT_I(inode)->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff; EXFAT_I(inode)->i_size_aligned = i_size_read(inode); EXFAT_I(inode)->i_size_ondisk = i_size_read(inode); -- 2.33.0