aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2011-04-18 17:29:14 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-04-18 17:29:14 -0400
commit2035e776050aea57fb5255557216473e82793f2c (patch)
tree6a97e536fd5fbdc29e4b471195a5dd5a0df35fc6 /fs/ext4/super.c
parent26626f1172fb4f3f323239a6a5cf4e082643fa46 (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.c74
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);
75static int ext4_freeze(struct super_block *sb); 75static int ext4_freeze(struct super_block *sb);
76static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, 76static 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);
78static inline int ext2_feature_set_ok(struct super_block *sb);
79static inline int ext3_feature_set_ok(struct super_block *sb);
78static int ext4_feature_set_ok(struct super_block *sb, int readonly); 80static int ext4_feature_set_ok(struct super_block *sb, int readonly);
79static void ext4_destroy_lazyinit_thread(void); 81static void ext4_destroy_lazyinit_thread(void);
80static void ext4_unregister_li_request(struct super_block *sb); 82static void ext4_unregister_li_request(struct super_block *sb);
81static void ext4_clear_request_list(void); 83static 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)
86static 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)
84static struct file_system_type ext3_fs_type = { 100static 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)
4775static 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
4783static inline void register_as_ext2(void) 4813static 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
4826static 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}
4795MODULE_ALIAS("ext2"); 4836MODULE_ALIAS("ext2");
4796#else 4837#else
4797static inline void register_as_ext2(void) { } 4838static inline void register_as_ext2(void) { }
4798static inline void unregister_as_ext2(void) { } 4839static inline void unregister_as_ext2(void) { }
4840static 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
4857static 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}
4814MODULE_ALIAS("ext3"); 4869MODULE_ALIAS("ext3");
4815#else 4870#else
4816static inline void register_as_ext3(void) { } 4871static inline void register_as_ext3(void) { }
4817static inline void unregister_as_ext3(void) { } 4872static inline void unregister_as_ext3(void) { }
4873static inline int ext3_feature_set_ok(struct super_block *sb) { return 0; }
4818#endif 4874#endif
4819 4875
4820static struct file_system_type ext4_fs_type = { 4876static 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;