On Sun, Jun 04, 2017 at 10:58:38PM +0100, Al Viro wrote: > u64 ufs_max_bytes(struct super_block *sb) > { > struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; > int bits = uspi->s_apbshift; > u64 res; > > if (bits > 21) > return MAX_LFS_FILESIZE; > > res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) + > (1LL << (3*bits)); > > if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift)) > return MAX_LFS_FILESIZE; > > return res << uspi->s_bshift; > } > > ought to calculate the right thing for modern UFS variants; I would > leave the anything other than UFS_MOUNT_UFSTYPE_44BSD and > UFS_MOUNT_UFSTYPE_UFS2 alone. Now that I'm hopefully sufficiently awake... Folks, could you try this: diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 131b2b77c818..2bab1491a5d4 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -746,6 +746,24 @@ static void ufs_put_super(struct super_block *sb) return; } +static u64 ufs_max_bytes(struct super_block *sb) +{ + struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; + int bits = uspi->s_apbshift; + u64 res; + + if (bits > 21) + return MAX_LFS_FILESIZE; + + res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) + + (1LL << (3*bits)); + + if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift)) + return MAX_LFS_FILESIZE; + + return res << uspi->s_bshift; +} + static int ufs_fill_super(struct super_block *sb, void *data, int silent) { struct ufs_sb_info * sbi; @@ -823,6 +841,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_fshift = 9; uspi->s_sbsize = super_block_size = 1536; uspi->s_sbbase = 0; + sb->s_maxbytes = ufs_max_bytes(sb); flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; break; case UFS_MOUNT_UFSTYPE_UFS2: @@ -833,6 +852,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_fshift = 9; uspi->s_sbsize = super_block_size = 1536; uspi->s_sbbase = 0; + sb->s_maxbytes = ufs_max_bytes(sb); flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; break;