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 |
