2009-12-02 01:44:11

by Philip Wernersbach

[permalink] [raw]
Subject: [PATCH] ext2/3 as ext4

Hello Everyone,
Below is a small patch I wrote for kernel version 2.6.31.6. It
causes ext2/3 filesystems to be mounted using the ext4 driver, in a
way that is transparent to the userspace (and kernelspace for that
matter, as long as the code uses the kernel's mounting API) and
requires no change to the userspace (/kernelspace). This patch is
useful because: 1) It allows minimalist kernel fanatics, like myself,
to drop 2 drivers from their builds without any loss in functionality.
2) It allows the ext2/3 filesystems to take advantage of the
performance/general improvements in the ext4 driver. 3) In the future,
with this patch, the ext2/3 driver code could be dropped from the
kernel without any loss in functionality. I have been using this patch
for 2 months now with no flaws on my home Linux box, which uses ext3
drives on a daily basis.

Let me know if you use this patch, if enough people use it I will
write a proper KCONFIG and submit it for inclusion into the kernel.

So without further ado, here is the patch.

Sincerely,
Philip Wernersbach <[email protected]>

--- linux-2.6.31.6.orig/fs/namespace.c 2009-11-28 22:30:07.178682500 -0500
+++ linux-2.6.31.6/fs/namespace.c 2009-11-28 22:32:42.813462139 -0500
@@ -6,6 +6,8 @@
*
* Based on code from fs/super.c, copyright Linus Torvalds and others.
* Heavily rewritten.
+ *
+ * Uses ext2/3 as ext4 patch by Philip Wernersbach (November 2009)
*/

#include <linux/syscalls.h>
@@ -1838,6 +1840,34 @@
return n;
}

+/*
+ * compare_fs_names(char *fs1, char *fs2) - Part of the ext2/3 as ext4 patch
+ *
+ * The following is a standard string compare function, made to compare
+ * filesystem names, it returns 0 if they equal, and 1 if they do not.
+ * It only handles strings up to 255 characters though, so be cautious.
+ */
+static int compare_fs_names(char *fs1, char *fs2)
+{
+ int i;
+
+ if (fs1 == 0L || fs2 == 0L) return 1;
+
+ for (i=0;i<256;i++)
+ {
+ if (fs1[i] != fs2[i])
+ return 1;
+ if (fs1[i] == 0 && fs2[i] == 0)
+ return 0;
+ if (fs1[i] == 0)
+ return 1;
+ if (fs2[i] == 0)
+ return 1;
+ }
+ return 0;
+}
+
+
int copy_mount_options(const void __user * data, unsigned long *where)
{
int i;
@@ -1891,6 +1921,22 @@
struct path path;
int retval = 0;
int mnt_flags = 0;
+
+ /*
+ * This causes ext2 filesystems to be mounted with the ext4 driver.
+ *
+ * Part of the ext2/3 as ext4 patch.
+ */
+ if (compare_fs_names(type_page, "ext2") == 0)
+ type_page[3] = '4';
+
+ /*
+ * This causes ext3 filesystems to be mounted with the ext4 driver.
+ *
+ * Part of the ext2/3 as ext4 patch.
+ */
+ if (compare_fs_names(type_page, "ext3") == 0)
+ type_page[3] = '4';

/* Discard magic */
if ((flags & MS_MGC_MSK) == MS_MGC_VAL)


2009-12-02 01:58:05

by Richard Holden

[permalink] [raw]
Subject: Re: [PATCH] ext2/3 as ext4

Philip Wernersbach wrote:
> Hello Everyone,
> Below is a small patch I wrote for kernel version 2.6.31.6. It
> causes ext2/3 filesystems to be mounted using the ext4 driver, in a
> way that is transparent to the userspace (and kernelspace for that
> matter, as long as the code uses the kernel's mounting API) and
> requires no change to the userspace (/kernelspace). This patch is
> useful because: 1) It allows minimalist kernel fanatics, like myself,
> to drop 2 drivers from their builds without any loss in functionality.
> 2) It allows the ext2/3 filesystems to take advantage of the
> performance/general improvements in the ext4 driver. 3) In the future,
> with this patch, the ext2/3 driver code could be dropped from the
> kernel without any loss in functionality. I have been using this patch
> for 2 months now with no flaws on my home Linux box, which uses ext3
> drives on a daily basis.

I will have to give this a try on few of my dev boxes and see how it
works out.

> Let me know if you use this patch, if enough people use it I will
> write a proper KCONFIG and submit it for inclusion into the kernel.
>
> So without further ado, here is the patch.
>
> Sincerely,
> Philip Wernersbach <[email protected]>
>
> --- linux-2.6.31.6.orig/fs/namespace.c 2009-11-28 22:30:07.178682500
-0500
> +++ linux-2.6.31.6/fs/namespace.c 2009-11-28 22:32:42.813462139
-0500
> @@ -6,6 +6,8 @@
> *
> * Based on code from fs/super.c, copyright Linus Torvalds and others.
> * Heavily rewritten.
> + *
> + * Uses ext2/3 as ext4 patch by Philip Wernersbach (November 2009)
> */
>
> #include <linux/syscalls.h>
> @@ -1838,6 +1840,34 @@
> return n;
> }
>
> +/*
> + * compare_fs_names(char *fs1, char *fs2) - Part of the ext2/3 as
ext4 patch
> + *
> + * The following is a standard string compare function, made to compare
> + * filesystem names, it returns 0 if they equal, and 1 if they do not.
> + * It only handles strings up to 255 characters though, so be cautious.
> + */
> +static int compare_fs_names(char *fs1, char *fs2)
> +{
> + int i;
> +
> + if (fs1 == 0L || fs2 == 0L) return 1;
> +
> + for (i=0;i<256;i++)
> + {
> + if (fs1[i] != fs2[i])
> + return 1;
> + if (fs1[i] == 0 && fs2[i] == 0)
> + return 0;
> + if (fs1[i] == 0)
> + return 1;
> + if (fs2[i] == 0)
> + return 1;
> + }
> + return 0;
> +}
> +
> +

Why the open coded strcmp?

> int copy_mount_options(const void __user * data, unsigned long *where)
> {
> int i;
> @@ -1891,6 +1921,22 @@
> struct path path;
> int retval = 0;
> int mnt_flags = 0;
> +
> + /*
> + * This causes ext2 filesystems to be mounted with the ext4
driver.
> + *
> + * Part of the ext2/3 as ext4 patch.
> + */
> + if (compare_fs_names(type_page, "ext2") == 0)
> + type_page[3] = '4';
> +
> + /*
> + * This causes ext3 filesystems to be mounted with the ext4
driver.
> + *
> + * Part of the ext2/3 as ext4 patch.
> + */
> + if (compare_fs_names(type_page, "ext3") == 0)
> + type_page[3] = '4';

I would put these 2 conditionals into a single if ||, and consolidate
the type_page setting into 1 place, then you limit where you handle the
ext2/ext3 filesystems inside of ext4.

>
> /* Discard magic */
> if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

-Richard Holden

2009-12-06 21:30:57

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH] ext2/3 as ext4


Hi!

> Hello Everyone,
> Below is a small patch I wrote for kernel version 2.6.31.6. It
> causes ext2/3 filesystems to be mounted using the ext4 driver, in a
> way that is transparent to the userspace (and kernelspace for that
> matter, as long as the code uses the kernel's mounting API) and
> requires no change to the userspace (/kernelspace). This patch is
> useful because: 1) It allows minimalist kernel fanatics, like myself,
> to drop 2 drivers from their builds without any loss in functionality.
> 2) It allows the ext2/3 filesystems to take advantage of the
> performance/general improvements in the ext4 driver. 3) In the future,
> with this patch, the ext2/3 driver code could be dropped from the
> kernel without any loss in functionality. I have been using this patch
> for 2 months now with no flaws on my home Linux box, which uses ext3
> drives on a daily basis.
>
> Let me know if you use this patch, if enough people use it I will
> write a proper KCONFIG and submit it for inclusion into the kernel.
>
> So without further ado, here is the patch.
>
> Sincerely,
> Philip Wernersbach <[email protected]>

(I believe patch was whitespace damaged).

> --- linux-2.6.31.6.orig/fs/namespace.c 2009-11-28 22:30:07.178682500 -0500
> +++ linux-2.6.31.6/fs/namespace.c 2009-11-28 22:32:42.813462139 -0500
> @@ -6,6 +6,8 @@
> *
> * Based on code from fs/super.c, copyright Linus Torvalds and others.
> * Heavily rewritten.
> + *
> + * Uses ext2/3 as ext4 patch by Philip Wernersbach (November 2009)
> */
>

Add yourself to the CREDITS; we don't use comments for changelog these days.

> +/*
> + * compare_fs_names(char *fs1, char *fs2) - Part of the ext2/3 as ext4 patch
> + *
> + * The following is a standard string compare function, made to compare
> + * filesystem names, it returns 0 if they equal, and 1 if they do not.
> + * It only handles strings up to 255 characters though, so be cautious.
> + */
> +static int compare_fs_names(char *fs1, char *fs2)
> +{
> + int i;
> +
> + if (fs1 == 0L || fs2 == 0L) return 1;

Ouch?

> + for (i=0;i<256;i++)
> + {
> + if (fs1[i] != fs2[i])
> + return 1;
> + if (fs1[i] == 0 && fs2[i] == 0)
> + return 0;
> + if (fs1[i] == 0)
> + return 1;
> + if (fs2[i] == 0)
> + return 1;
> + }
> + return 0;

Can you use memcmp, instead?

> @@ -1891,6 +1921,22 @@
> struct path path;
> int retval = 0;
> int mnt_flags = 0;
> +
> + /*
> + * This causes ext2 filesystems to be mounted with the ext4 driver.
> + *
> + * Part of the ext2/3 as ext4 patch.
> + */
> + if (compare_fs_names(type_page, "ext2") == 0)
> + type_page[3] = '4';

Actualy strcmp() may be appropriate.

Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-12-07 19:09:47

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] ext2/3 as ext4

On Tue, Dec 01, 2009 at 08:30:36PM -0500, Philip Wernersbach wrote:
> Hello Everyone,
> Below is a small patch I wrote for kernel version 2.6.31.6. It
> causes ext2/3 filesystems to be mounted using the ext4 driver, in a
> way that is transparent to the userspace (and kernelspace for that
> matter, as long as the code uses the kernel's mounting API) and
> requires no change to the userspace (/kernelspace). This patch is
> useful because: 1) It allows minimalist kernel fanatics, like myself,
> to drop 2 drivers from their builds without any loss in functionality.
> 2) It allows the ext2/3 filesystems to take advantage of the
> performance/general improvements in the ext4 driver. 3) In the future,
> with this patch, the ext2/3 driver code could be dropped from the
> kernel without any loss in functionality.

Here's a much cleaner patch which achieves the same goal...

- Ted

commit 46b5cb9a4a4c7cf8735ab0f7ae0c876664e750cb
Author: Theodore Ts'o <[email protected]>
Date: Mon Dec 7 14:08:51 2009 -0500

ext4: Use ext4 file system driver for ext2/ext3 file system mounts

Add a new config option, CONFIG_EXT4_USE_FOR_EXT23 which if enabled,
will cause ext4 to be used for either ext2 or ext3 file system mounts
when ext2 or ext3 is not enabled in the configuration.

This allows minimalist kernel fanatics to drop to file system drivers
from their compiled kernel with out losing functionality.

Signed-off-by: "Theodore Ts'o" <[email protected]>

diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 9f2d45d..a6b4e93 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -26,6 +26,16 @@ config EXT4_FS

If unsure, say N.

+config EXT4_USE_FOR_EXT23
+ bool "Use ext4 for ext2/ext3 file systems"
+ depends on !EXT3_FS || !EXT2_FS
+ default y
+ help
+ Allow the ext4 file system driver code to be used for ext2 or
+ ext3 file system mounts. This allows users to reduce their
+ compiled kernel size by using one file system driver for
+ ext2, ext3, and ext4 file systems.
+
config EXT4_FS_XATTR
bool "Ext4 extended attributes"
depends on EXT4_FS
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 5a2db61..30476da 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3960,6 +3960,58 @@ static int ext4_get_sb(struct file_system_type *fs_type, int flags,
return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
}

+#if !defined(CONTIG_EXT2_FS) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+static struct file_system_type ext2_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "ext2",
+ .get_sb = ext4_get_sb,
+ .kill_sb = kill_block_super,
+ .fs_flags = FS_REQUIRES_DEV,
+};
+
+static inline void register_as_ext2(void)
+{
+ int err = register_filesystem(&ext2_fs_type);
+ if (err)
+ printk(KERN_WARNING
+ "EXT4-fs: Unable to register as ext2 (%d)\n", err);
+}
+
+static inline void unregister_as_ext2(void)
+{
+ unregister_filesystem(&ext2_fs_type);
+}
+#else
+static inline void register_as_ext2(void) { }
+static inline void unregister_as_ext2(void) { }
+#endif
+
+#if !defined(CONTIG_EXT3_FS) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+static struct file_system_type ext3_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "ext3",
+ .get_sb = ext4_get_sb,
+ .kill_sb = kill_block_super,
+ .fs_flags = FS_REQUIRES_DEV,
+};
+
+static inline void register_as_ext3(void)
+{
+ int err = register_filesystem(&ext3_fs_type);
+ if (err)
+ printk(KERN_WARNING
+ "EXT4-fs: Unable to register as ext3 (%d)\n", err);
+}
+
+static inline void unregister_as_ext3(void)
+{
+ unregister_filesystem(&ext3_fs_type);
+}
+#else
+static inline void register_as_ext3(void) { }
+static inline void unregister_as_ext3(void) { }
+#endif
+
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
@@ -3989,11 +4041,15 @@ static int __init init_ext4_fs(void)
err = init_inodecache();
if (err)
goto out1;
+ register_as_ext2();
+ register_as_ext3();
err = register_filesystem(&ext4_fs_type);
if (err)
goto out;
return 0;
out:
+ unregister_as_ext2();
+ unregister_as_ext3();
destroy_inodecache();
out1:
exit_ext4_xattr();
@@ -4009,6 +4065,8 @@ out4:

static void __exit exit_ext4_fs(void)
{
+ unregister_as_ext2();
+ unregister_as_ext3();
unregister_filesystem(&ext4_fs_type);
destroy_inodecache();
exit_ext4_xattr();

2009-12-17 00:42:40

by Philip Wernersbach

[permalink] [raw]
Subject: Re: [PATCH] ext2/3 as ext4

> Why the open coded strcmp?
strcmp is a C standard library function, not a C builtin, thus it
can't be used in the kernel.

> I would put these 2 conditionals into a single if ||, and consolidate
> the type_page setting into 1 place, then you limit where you handle the
> ext2/ext3 filesystems inside of ext4.
Thanks, that's a good idea.

> (I believe patch was whitespace damaged).
Oops! It was, sorry about that.

> Add yourself to the CREDITS; we don't use comments for changelog these days.
Okay.

> Ouch?
I don't see the problem, please elaborate.

> Can you use memcmp, instead?
No, it's a C standard library function.

> Actualy strcmp() may be appropriate.
It would, but that's also a C standard library function.

> Here's a much cleaner patch which achieves the same goal...
Thanks Ted, that is much cleaner, although I think it would be better
to have separate KCONFIG options for mounting ext2 as ext4 and ext3 as
ext4. I can code this in when I get some time.

Thanks,
Phil

2009-12-22 01:14:34

by Robert Hancock

[permalink] [raw]
Subject: Re: [PATCH] ext2/3 as ext4

On 12/16/2009 06:42 PM, Philip Wernersbach wrote:
>> Why the open coded strcmp?
> strcmp is a C standard library function, not a C builtin, thus it
> can't be used in the kernel.

Um, we do have strcmp, memcmp, and most such common library functions in
the kernel..

2009-12-27 07:56:53

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH] ext2/3 as ext4

Hi Ted,

On Mon, Dec 07, 2009 at 02:09:47PM -0500, [email protected] wrote:
> On Tue, Dec 01, 2009 at 08:30:36PM -0500, Philip Wernersbach wrote:
> > Hello Everyone,
> > Below is a small patch I wrote for kernel version 2.6.31.6. It
> > causes ext2/3 filesystems to be mounted using the ext4 driver, in a
> > way that is transparent to the userspace (and kernelspace for that
> > matter, as long as the code uses the kernel's mounting API) and
> > requires no change to the userspace (/kernelspace). This patch is
> > useful because: 1) It allows minimalist kernel fanatics, like myself,
> > to drop 2 drivers from their builds without any loss in functionality.
> > 2) It allows the ext2/3 filesystems to take advantage of the
> > performance/general improvements in the ext4 driver. 3) In the future,
> > with this patch, the ext2/3 driver code could be dropped from the
> > kernel without any loss in functionality.
>
> Here's a much cleaner patch which achieves the same goal...
>

I experience regular crashes with 2.6.32-rc2 that seem to be related to
this patch as thet seem to go away if I enable proper ext3 support.

Kernel BUG()s out in ext4_da_update_reserve_space(); unofrtunately
traces don't make it ot the disk but I managed to snatch a picture with
my didgital camera:

http://userweb.kernel.org/~dtor/ext4-oops.jpg

I also tried pulling your latest pull request for Linus but the behavior
is the same.

Thanks.

--
Dmitry