diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b806e689c4aa..6dcbb28dc06d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/namei.h> | 36 | #include <linux/namei.h> |
37 | #include <linux/quotaops.h> | 37 | #include <linux/quotaops.h> |
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/log2.h> | ||
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | 42 | ||
@@ -734,7 +735,7 @@ enum { | |||
734 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 735 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
735 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 736 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
736 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 737 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
737 | Opt_grpquota, Opt_extents, | 738 | Opt_grpquota, Opt_extents, Opt_noextents, |
738 | }; | 739 | }; |
739 | 740 | ||
740 | static match_table_t tokens = { | 741 | static match_table_t tokens = { |
@@ -785,6 +786,7 @@ static match_table_t tokens = { | |||
785 | {Opt_usrquota, "usrquota"}, | 786 | {Opt_usrquota, "usrquota"}, |
786 | {Opt_barrier, "barrier=%u"}, | 787 | {Opt_barrier, "barrier=%u"}, |
787 | {Opt_extents, "extents"}, | 788 | {Opt_extents, "extents"}, |
789 | {Opt_noextents, "noextents"}, | ||
788 | {Opt_err, NULL}, | 790 | {Opt_err, NULL}, |
789 | {Opt_resize, "resize"}, | 791 | {Opt_resize, "resize"}, |
790 | }; | 792 | }; |
@@ -1120,6 +1122,9 @@ clear_qf_name: | |||
1120 | case Opt_extents: | 1122 | case Opt_extents: |
1121 | set_opt (sbi->s_mount_opt, EXTENTS); | 1123 | set_opt (sbi->s_mount_opt, EXTENTS); |
1122 | break; | 1124 | break; |
1125 | case Opt_noextents: | ||
1126 | clear_opt (sbi->s_mount_opt, EXTENTS); | ||
1127 | break; | ||
1123 | default: | 1128 | default: |
1124 | printk (KERN_ERR | 1129 | printk (KERN_ERR |
1125 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1130 | "EXT4-fs: Unrecognized mount option \"%s\" " |
@@ -1551,6 +1556,12 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1551 | 1556 | ||
1552 | set_opt(sbi->s_mount_opt, RESERVATION); | 1557 | set_opt(sbi->s_mount_opt, RESERVATION); |
1553 | 1558 | ||
1559 | /* | ||
1560 | * turn on extents feature by default in ext4 filesystem | ||
1561 | * User -o noextents to turn it off | ||
1562 | */ | ||
1563 | set_opt(sbi->s_mount_opt, EXTENTS); | ||
1564 | |||
1554 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, | 1565 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, |
1555 | NULL, 0)) | 1566 | NULL, 0)) |
1556 | goto failed_mount; | 1567 | goto failed_mount; |
@@ -1634,13 +1645,15 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1634 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); | 1645 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); |
1635 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); | 1646 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); |
1636 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || | 1647 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || |
1637 | (sbi->s_inode_size & (sbi->s_inode_size - 1)) || | 1648 | (!is_power_of_2(sbi->s_inode_size)) || |
1638 | (sbi->s_inode_size > blocksize)) { | 1649 | (sbi->s_inode_size > blocksize)) { |
1639 | printk (KERN_ERR | 1650 | printk (KERN_ERR |
1640 | "EXT4-fs: unsupported inode size: %d\n", | 1651 | "EXT4-fs: unsupported inode size: %d\n", |
1641 | sbi->s_inode_size); | 1652 | sbi->s_inode_size); |
1642 | goto failed_mount; | 1653 | goto failed_mount; |
1643 | } | 1654 | } |
1655 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) | ||
1656 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); | ||
1644 | } | 1657 | } |
1645 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << | 1658 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << |
1646 | le32_to_cpu(es->s_log_frag_size); | 1659 | le32_to_cpu(es->s_log_frag_size); |
@@ -1803,6 +1816,13 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1803 | goto failed_mount3; | 1816 | goto failed_mount3; |
1804 | } | 1817 | } |
1805 | 1818 | ||
1819 | if (ext4_blocks_count(es) > 0xffffffffULL && | ||
1820 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | ||
1821 | JBD2_FEATURE_INCOMPAT_64BIT)) { | ||
1822 | printk(KERN_ERR "ext4: Failed to set 64-bit journal feature\n"); | ||
1823 | goto failed_mount4; | ||
1824 | } | ||
1825 | |||
1806 | /* We have now updated the journal if required, so we can | 1826 | /* We have now updated the journal if required, so we can |
1807 | * validate the data journaling mode. */ | 1827 | * validate the data journaling mode. */ |
1808 | switch (test_opt(sb, DATA_FLAGS)) { | 1828 | switch (test_opt(sb, DATA_FLAGS)) { |
@@ -1857,6 +1877,32 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1857 | } | 1877 | } |
1858 | 1878 | ||
1859 | ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 1879 | ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
1880 | |||
1881 | /* determine the minimum size of new large inodes, if present */ | ||
1882 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) { | ||
1883 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | ||
1884 | EXT4_GOOD_OLD_INODE_SIZE; | ||
1885 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
1886 | EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) { | ||
1887 | if (sbi->s_want_extra_isize < | ||
1888 | le16_to_cpu(es->s_want_extra_isize)) | ||
1889 | sbi->s_want_extra_isize = | ||
1890 | le16_to_cpu(es->s_want_extra_isize); | ||
1891 | if (sbi->s_want_extra_isize < | ||
1892 | le16_to_cpu(es->s_min_extra_isize)) | ||
1893 | sbi->s_want_extra_isize = | ||
1894 | le16_to_cpu(es->s_min_extra_isize); | ||
1895 | } | ||
1896 | } | ||
1897 | /* Check if enough inode space is available */ | ||
1898 | if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > | ||
1899 | sbi->s_inode_size) { | ||
1900 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | ||
1901 | EXT4_GOOD_OLD_INODE_SIZE; | ||
1902 | printk(KERN_INFO "EXT4-fs: required extra inode space not" | ||
1903 | "available.\n"); | ||
1904 | } | ||
1905 | |||
1860 | /* | 1906 | /* |
1861 | * akpm: core read_super() calls in here with the superblock locked. | 1907 | * akpm: core read_super() calls in here with the superblock locked. |
1862 | * That deadlocks, because orphan cleanup needs to lock the superblock | 1908 | * That deadlocks, because orphan cleanup needs to lock the superblock |