diff options
author | Theodore Ts'o <tytso@mit.edu> | 2011-04-18 17:29:14 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-04-18 17:29:14 -0400 |
commit | 2035e776050aea57fb5255557216473e82793f2c (patch) | |
tree | 6a97e536fd5fbdc29e4b471195a5dd5a0df35fc6 /fs/ext4/super.c | |
parent | 26626f1172fb4f3f323239a6a5cf4e082643fa46 (diff) |
ext4: check for ext[23] file system features when mounting as ext[23]
Provide better emulation for ext[23] mode by enforcing that the file
system does not have any unsupported file system features as defined
by ext[23] when emulating the ext[23] file system driver when
CONFIG_EXT4_USE_FOR_EXT23 is defined.
This causes the file system type information in /proc/mounts to be
correct for the automatically mounted root file system. This also
means that "mount -t ext2 /dev/sda /mnt" will fail if /dev/sda
contains an ext3 or ext4 file system, just as one would expect if the
original ext2 file system driver were in use.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8553dfb310af..cb22783a4377 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -75,11 +75,27 @@ static void ext4_write_super(struct super_block *sb); | |||
75 | static int ext4_freeze(struct super_block *sb); | 75 | static int ext4_freeze(struct super_block *sb); |
76 | static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, | 76 | static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, |
77 | const char *dev_name, void *data); | 77 | const char *dev_name, void *data); |
78 | static inline int ext2_feature_set_ok(struct super_block *sb); | ||
79 | static inline int ext3_feature_set_ok(struct super_block *sb); | ||
78 | static int ext4_feature_set_ok(struct super_block *sb, int readonly); | 80 | static int ext4_feature_set_ok(struct super_block *sb, int readonly); |
79 | static void ext4_destroy_lazyinit_thread(void); | 81 | static void ext4_destroy_lazyinit_thread(void); |
80 | static void ext4_unregister_li_request(struct super_block *sb); | 82 | static void ext4_unregister_li_request(struct super_block *sb); |
81 | static void ext4_clear_request_list(void); | 83 | static void ext4_clear_request_list(void); |
82 | 84 | ||
85 | #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | ||
86 | static struct file_system_type ext2_fs_type = { | ||
87 | .owner = THIS_MODULE, | ||
88 | .name = "ext2", | ||
89 | .mount = ext4_mount, | ||
90 | .kill_sb = kill_block_super, | ||
91 | .fs_flags = FS_REQUIRES_DEV, | ||
92 | }; | ||
93 | #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type) | ||
94 | #else | ||
95 | #define IS_EXT2_SB(sb) (0) | ||
96 | #endif | ||
97 | |||
98 | |||
83 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | 99 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |
84 | static struct file_system_type ext3_fs_type = { | 100 | static struct file_system_type ext3_fs_type = { |
85 | .owner = THIS_MODULE, | 101 | .owner = THIS_MODULE, |
@@ -3187,6 +3203,28 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3187 | "feature flags set on rev 0 fs, " | 3203 | "feature flags set on rev 0 fs, " |
3188 | "running e2fsck is recommended"); | 3204 | "running e2fsck is recommended"); |
3189 | 3205 | ||
3206 | if (IS_EXT2_SB(sb)) { | ||
3207 | if (ext2_feature_set_ok(sb)) | ||
3208 | ext4_msg(sb, KERN_INFO, "mounting ext2 file system " | ||
3209 | "using the ext4 subsystem"); | ||
3210 | else { | ||
3211 | ext4_msg(sb, KERN_ERR, "couldn't mount as ext2 due " | ||
3212 | "to feature incompatibilities"); | ||
3213 | goto failed_mount; | ||
3214 | } | ||
3215 | } | ||
3216 | |||
3217 | if (IS_EXT3_SB(sb)) { | ||
3218 | if (ext3_feature_set_ok(sb)) | ||
3219 | ext4_msg(sb, KERN_INFO, "mounting ext3 file system " | ||
3220 | "using the ext4 subsystem"); | ||
3221 | else { | ||
3222 | ext4_msg(sb, KERN_ERR, "couldn't mount as ext3 due " | ||
3223 | "to feature incompatibilities"); | ||
3224 | goto failed_mount; | ||
3225 | } | ||
3226 | } | ||
3227 | |||
3190 | /* | 3228 | /* |
3191 | * Check feature flags regardless of the revision level, since we | 3229 | * Check feature flags regardless of the revision level, since we |
3192 | * previously didn't change the revision level when setting the flags, | 3230 | * previously didn't change the revision level when setting the flags, |
@@ -4772,14 +4810,6 @@ static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, | |||
4772 | } | 4810 | } |
4773 | 4811 | ||
4774 | #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | 4812 | #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |
4775 | static struct file_system_type ext2_fs_type = { | ||
4776 | .owner = THIS_MODULE, | ||
4777 | .name = "ext2", | ||
4778 | .mount = ext4_mount, | ||
4779 | .kill_sb = kill_block_super, | ||
4780 | .fs_flags = FS_REQUIRES_DEV, | ||
4781 | }; | ||
4782 | |||
4783 | static inline void register_as_ext2(void) | 4813 | static inline void register_as_ext2(void) |
4784 | { | 4814 | { |
4785 | int err = register_filesystem(&ext2_fs_type); | 4815 | int err = register_filesystem(&ext2_fs_type); |
@@ -4792,10 +4822,22 @@ static inline void unregister_as_ext2(void) | |||
4792 | { | 4822 | { |
4793 | unregister_filesystem(&ext2_fs_type); | 4823 | unregister_filesystem(&ext2_fs_type); |
4794 | } | 4824 | } |
4825 | |||
4826 | static inline int ext2_feature_set_ok(struct super_block *sb) | ||
4827 | { | ||
4828 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP)) | ||
4829 | return 0; | ||
4830 | if (sb->s_flags & MS_RDONLY) | ||
4831 | return 1; | ||
4832 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP)) | ||
4833 | return 0; | ||
4834 | return 1; | ||
4835 | } | ||
4795 | MODULE_ALIAS("ext2"); | 4836 | MODULE_ALIAS("ext2"); |
4796 | #else | 4837 | #else |
4797 | static inline void register_as_ext2(void) { } | 4838 | static inline void register_as_ext2(void) { } |
4798 | static inline void unregister_as_ext2(void) { } | 4839 | static inline void unregister_as_ext2(void) { } |
4840 | static inline int ext2_feature_set_ok(struct super_block *sb) { return 0; } | ||
4799 | #endif | 4841 | #endif |
4800 | 4842 | ||
4801 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | 4843 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |
@@ -4811,10 +4853,24 @@ static inline void unregister_as_ext3(void) | |||
4811 | { | 4853 | { |
4812 | unregister_filesystem(&ext3_fs_type); | 4854 | unregister_filesystem(&ext3_fs_type); |
4813 | } | 4855 | } |
4856 | |||
4857 | static inline int ext3_feature_set_ok(struct super_block *sb) | ||
4858 | { | ||
4859 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP)) | ||
4860 | return 0; | ||
4861 | if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) | ||
4862 | return 0; | ||
4863 | if (sb->s_flags & MS_RDONLY) | ||
4864 | return 1; | ||
4865 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP)) | ||
4866 | return 0; | ||
4867 | return 1; | ||
4868 | } | ||
4814 | MODULE_ALIAS("ext3"); | 4869 | MODULE_ALIAS("ext3"); |
4815 | #else | 4870 | #else |
4816 | static inline void register_as_ext3(void) { } | 4871 | static inline void register_as_ext3(void) { } |
4817 | static inline void unregister_as_ext3(void) { } | 4872 | static inline void unregister_as_ext3(void) { } |
4873 | static inline int ext3_feature_set_ok(struct super_block *sb) { return 0; } | ||
4818 | #endif | 4874 | #endif |
4819 | 4875 | ||
4820 | static struct file_system_type ext4_fs_type = { | 4876 | static struct file_system_type ext4_fs_type = { |
@@ -4898,8 +4954,8 @@ static int __init ext4_init_fs(void) | |||
4898 | err = init_inodecache(); | 4954 | err = init_inodecache(); |
4899 | if (err) | 4955 | if (err) |
4900 | goto out1; | 4956 | goto out1; |
4901 | register_as_ext2(); | ||
4902 | register_as_ext3(); | 4957 | register_as_ext3(); |
4958 | register_as_ext2(); | ||
4903 | err = register_filesystem(&ext4_fs_type); | 4959 | err = register_filesystem(&ext4_fs_type); |
4904 | if (err) | 4960 | if (err) |
4905 | goto out; | 4961 | goto out; |