aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7be27dbe76bf..2b9dc96ec43e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1603,17 +1603,50 @@ static void ext4_orphan_cleanup (struct super_block * sb,
1603 1603
1604/* 1604/*
1605 * Maximal file size. There is a direct, and {,double-,triple-}indirect 1605 * Maximal file size. There is a direct, and {,double-,triple-}indirect
1606 * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. 1606 * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
1607 * We need to be 1 filesystem block less than the 2^32 sector limit. 1607 * We need to be 1 filesystem block less than the 2^48 sector limit.
1608 */ 1608 */
1609static loff_t ext4_max_size(int bits) 1609static loff_t ext4_max_size(int bits)
1610{ 1610{
1611 loff_t res = EXT4_NDIR_BLOCKS; 1611 loff_t res = EXT4_NDIR_BLOCKS;
1612 /* This constant is calculated to be the largest file size for a 1612 int meta_blocks;
1613 * dense, 4k-blocksize file such that the total number of 1613 loff_t upper_limit;
1614 /* This is calculated to be the largest file size for a
1615 * dense, file such that the total number of
1614 * sectors in the file, including data and all indirect blocks, 1616 * sectors in the file, including data and all indirect blocks,
1615 * does not exceed 2^32. */ 1617 * does not exceed 2^48 -1
1616 const loff_t upper_limit = 0x1ff7fffd000LL; 1618 * __u32 i_blocks_lo and _u16 i_blocks_high representing the
1619 * total number of 512 bytes blocks of the file
1620 */
1621
1622 if (sizeof(blkcnt_t) < sizeof(u64)) {
1623 /*
1624 * CONFIG_LSF is not enabled implies the inode
1625 * i_block represent total blocks in 512 bytes
1626 * 32 == size of vfs inode i_blocks * 8
1627 */
1628 upper_limit = (1LL << 32) - 1;
1629
1630 /* total blocks in file system block size */
1631 upper_limit >>= (bits - 9);
1632
1633 } else {
1634 /* We use 48 bit ext4_inode i_blocks */
1635 upper_limit = (1LL << 48) - 1;
1636
1637 /* total blocks in file system block size */
1638 upper_limit >>= (bits - 9);
1639 }
1640
1641 /* indirect blocks */
1642 meta_blocks = 1;
1643 /* double indirect blocks */
1644 meta_blocks += 1 + (1LL << (bits-2));
1645 /* tripple indirect blocks */
1646 meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
1647
1648 upper_limit -= meta_blocks;
1649 upper_limit <<= bits;
1617 1650
1618 res += 1LL << (bits-2); 1651 res += 1LL << (bits-2);
1619 res += 1LL << (2*(bits-2)); 1652 res += 1LL << (2*(bits-2));
@@ -1621,6 +1654,10 @@ static loff_t ext4_max_size(int bits)
1621 res <<= bits; 1654 res <<= bits;
1622 if (res > upper_limit) 1655 if (res > upper_limit)
1623 res = upper_limit; 1656 res = upper_limit;
1657
1658 if (res > MAX_LFS_FILESIZE)
1659 res = MAX_LFS_FILESIZE;
1660
1624 return res; 1661 return res;
1625} 1662}
1626 1663
@@ -1789,6 +1826,19 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1789 sb->s_id, le32_to_cpu(features)); 1826 sb->s_id, le32_to_cpu(features));
1790 goto failed_mount; 1827 goto failed_mount;
1791 } 1828 }
1829 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
1830 /*
1831 * Large file size enabled file system can only be
1832 * mount if kernel is build with CONFIG_LSF
1833 */
1834 if (sizeof(root->i_blocks) < sizeof(u64) &&
1835 !(sb->s_flags & MS_RDONLY)) {
1836 printk(KERN_ERR "EXT4-fs: %s: Filesystem with huge "
1837 "files cannot be mounted read-write "
1838 "without CONFIG_LSF.\n", sb->s_id);
1839 goto failed_mount;
1840 }
1841 }
1792 blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); 1842 blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
1793 1843
1794 if (blocksize < EXT4_MIN_BLOCK_SIZE || 1844 if (blocksize < EXT4_MIN_BLOCK_SIZE ||