aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c24
-rw-r--r--fs/ext4/super.c85
2 files changed, 21 insertions, 88 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 27fc6b951221..8dbf6953845b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4194,7 +4194,6 @@ static int ext4_inode_blocks_set(handle_t *handle,
4194 struct inode *inode = &(ei->vfs_inode); 4194 struct inode *inode = &(ei->vfs_inode);
4195 u64 i_blocks = inode->i_blocks; 4195 u64 i_blocks = inode->i_blocks;
4196 struct super_block *sb = inode->i_sb; 4196 struct super_block *sb = inode->i_sb;
4197 int err = 0;
4198 4197
4199 if (i_blocks <= ~0U) { 4198 if (i_blocks <= ~0U) {
4200 /* 4199 /*
@@ -4204,36 +4203,27 @@ static int ext4_inode_blocks_set(handle_t *handle,
4204 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); 4203 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
4205 raw_inode->i_blocks_high = 0; 4204 raw_inode->i_blocks_high = 0;
4206 ei->i_flags &= ~EXT4_HUGE_FILE_FL; 4205 ei->i_flags &= ~EXT4_HUGE_FILE_FL;
4207 } else if (i_blocks <= 0xffffffffffffULL) { 4206 return 0;
4207 }
4208 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
4209 return -EFBIG;
4210
4211 if (i_blocks <= 0xffffffffffffULL) {
4208 /* 4212 /*
4209 * i_blocks can be represented in a 48 bit variable 4213 * i_blocks can be represented in a 48 bit variable
4210 * as multiple of 512 bytes 4214 * as multiple of 512 bytes
4211 */ 4215 */
4212 err = ext4_update_rocompat_feature(handle, sb,
4213 EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
4214 if (err)
4215 goto err_out;
4216 /* i_block is stored in the split 48 bit fields */
4217 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); 4216 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
4218 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); 4217 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
4219 ei->i_flags &= ~EXT4_HUGE_FILE_FL; 4218 ei->i_flags &= ~EXT4_HUGE_FILE_FL;
4220 } else { 4219 } else {
4221 /*
4222 * i_blocks should be represented in a 48 bit variable
4223 * as multiple of file system block size
4224 */
4225 err = ext4_update_rocompat_feature(handle, sb,
4226 EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
4227 if (err)
4228 goto err_out;
4229 ei->i_flags |= EXT4_HUGE_FILE_FL; 4220 ei->i_flags |= EXT4_HUGE_FILE_FL;
4230 /* i_block is stored in file system block size */ 4221 /* i_block is stored in file system block size */
4231 i_blocks = i_blocks >> (inode->i_blkbits - 9); 4222 i_blocks = i_blocks >> (inode->i_blkbits - 9);
4232 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); 4223 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
4233 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); 4224 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
4234 } 4225 }
4235err_out: 4226 return 0;
4236 return err;
4237} 4227}
4238 4228
4239/* 4229/*
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 95127f03d1f6..9b2b2bc4ec17 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -374,66 +374,6 @@ void ext4_update_dynamic_rev(struct super_block *sb)
374 */ 374 */
375} 375}
376 376
377int ext4_update_compat_feature(handle_t *handle,
378 struct super_block *sb, __u32 compat)
379{
380 int err = 0;
381 if (!EXT4_HAS_COMPAT_FEATURE(sb, compat)) {
382 err = ext4_journal_get_write_access(handle,
383 EXT4_SB(sb)->s_sbh);
384 if (err)
385 return err;
386 EXT4_SET_COMPAT_FEATURE(sb, compat);
387 sb->s_dirt = 1;
388 handle->h_sync = 1;
389 BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
390 "call ext4_journal_dirty_met adata");
391 err = ext4_journal_dirty_metadata(handle,
392 EXT4_SB(sb)->s_sbh);
393 }
394 return err;
395}
396
397int ext4_update_rocompat_feature(handle_t *handle,
398 struct super_block *sb, __u32 rocompat)
399{
400 int err = 0;
401 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, rocompat)) {
402 err = ext4_journal_get_write_access(handle,
403 EXT4_SB(sb)->s_sbh);
404 if (err)
405 return err;
406 EXT4_SET_RO_COMPAT_FEATURE(sb, rocompat);
407 sb->s_dirt = 1;
408 handle->h_sync = 1;
409 BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
410 "call ext4_journal_dirty_met adata");
411 err = ext4_journal_dirty_metadata(handle,
412 EXT4_SB(sb)->s_sbh);
413 }
414 return err;
415}
416
417int ext4_update_incompat_feature(handle_t *handle,
418 struct super_block *sb, __u32 incompat)
419{
420 int err = 0;
421 if (!EXT4_HAS_INCOMPAT_FEATURE(sb, incompat)) {
422 err = ext4_journal_get_write_access(handle,
423 EXT4_SB(sb)->s_sbh);
424 if (err)
425 return err;
426 EXT4_SET_INCOMPAT_FEATURE(sb, incompat);
427 sb->s_dirt = 1;
428 handle->h_sync = 1;
429 BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
430 "call ext4_journal_dirty_met adata");
431 err = ext4_journal_dirty_metadata(handle,
432 EXT4_SB(sb)->s_sbh);
433 }
434 return err;
435}
436
437/* 377/*
438 * Open the external journal device 378 * Open the external journal device
439 */ 379 */
@@ -1771,13 +1711,13 @@ static void ext4_orphan_cleanup(struct super_block *sb,
1771 * 1711 *
1772 * Note, this does *not* consider any metadata overhead for vfs i_blocks. 1712 * Note, this does *not* consider any metadata overhead for vfs i_blocks.
1773 */ 1713 */
1774static loff_t ext4_max_size(int blkbits) 1714static loff_t ext4_max_size(int blkbits, int has_huge_files)
1775{ 1715{
1776 loff_t res; 1716 loff_t res;
1777 loff_t upper_limit = MAX_LFS_FILESIZE; 1717 loff_t upper_limit = MAX_LFS_FILESIZE;
1778 1718
1779 /* small i_blocks in vfs inode? */ 1719 /* small i_blocks in vfs inode? */
1780 if (sizeof(blkcnt_t) < sizeof(u64)) { 1720 if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
1781 /* 1721 /*
1782 * CONFIG_LSF is not enabled implies the inode 1722 * CONFIG_LSF is not enabled implies the inode
1783 * i_block represent total blocks in 512 bytes 1723 * i_block represent total blocks in 512 bytes
@@ -1807,7 +1747,7 @@ static loff_t ext4_max_size(int blkbits)
1807 * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks. 1747 * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
1808 * We need to be 1 filesystem block less than the 2^48 sector limit. 1748 * We need to be 1 filesystem block less than the 2^48 sector limit.
1809 */ 1749 */
1810static loff_t ext4_max_bitmap_size(int bits) 1750static loff_t ext4_max_bitmap_size(int bits, int has_huge_files)
1811{ 1751{
1812 loff_t res = EXT4_NDIR_BLOCKS; 1752 loff_t res = EXT4_NDIR_BLOCKS;
1813 int meta_blocks; 1753 int meta_blocks;
@@ -1820,11 +1760,11 @@ static loff_t ext4_max_bitmap_size(int bits)
1820 * total number of 512 bytes blocks of the file 1760 * total number of 512 bytes blocks of the file
1821 */ 1761 */
1822 1762
1823 if (sizeof(blkcnt_t) < sizeof(u64)) { 1763 if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
1824 /* 1764 /*
1825 * CONFIG_LSF is not enabled implies the inode 1765 * !has_huge_files or CONFIG_LSF is not enabled
1826 * i_block represent total blocks in 512 bytes 1766 * implies the inode i_block represent total blocks in
1827 * 32 == size of vfs inode i_blocks * 8 1767 * 512 bytes 32 == size of vfs inode i_blocks * 8
1828 */ 1768 */
1829 upper_limit = (1LL << 32) - 1; 1769 upper_limit = (1LL << 32) - 1;
1830 1770
@@ -1933,7 +1873,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
1933 int blocksize; 1873 int blocksize;
1934 int db_count; 1874 int db_count;
1935 int i; 1875 int i;
1936 int needs_recovery; 1876 int needs_recovery, has_huge_files;
1937 __le32 features; 1877 __le32 features;
1938 __u64 blocks_count; 1878 __u64 blocks_count;
1939 int err; 1879 int err;
@@ -2074,7 +2014,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2074 sb->s_id, le32_to_cpu(features)); 2014 sb->s_id, le32_to_cpu(features));
2075 goto failed_mount; 2015 goto failed_mount;
2076 } 2016 }
2077 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) { 2017 has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
2018 EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
2019 if (has_huge_files) {
2078 /* 2020 /*
2079 * Large file size enabled file system can only be 2021 * Large file size enabled file system can only be
2080 * mount if kernel is build with CONFIG_LSF 2022 * mount if kernel is build with CONFIG_LSF
@@ -2124,8 +2066,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2124 } 2066 }
2125 } 2067 }
2126 2068
2127 sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits); 2069 sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
2128 sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits); 2070 has_huge_files);
2071 sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
2129 2072
2130 if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { 2073 if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) {
2131 sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; 2074 sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE;