--- /dev/null
+Signed-off-by: Johann Lombardi <johann.lombardi@bull.net>
+
+Index: linux-2.6.9-full/fs/ext3/super.c
+===================================================================
+--- linux-2.6.9-full.orig/fs/ext3/super.c 2006-05-20 01:14:14.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/super.c 2006-05-20 01:17:10.000000000 +0400
+@@ -39,7 +39,8 @@
+ #include "acl.h"
+ #include "group.h"
+
+-static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
++static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
++ unsigned long journal_devnum);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+ int);
+ void ext3_commit_super (struct super_block * sb,
+@@ -591,7 +592,7 @@ enum {
+ Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
+ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+ Opt_reservation, Opt_noreservation, Opt_noload,
+- Opt_commit, Opt_journal_update, Opt_journal_inum,
++ Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
+ Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+ Opt_ignore, Opt_barrier,
+ Opt_err,
+@@ -630,6 +631,7 @@ static match_table_t tokens = {
+ {Opt_commit, "commit=%u"},
+ {Opt_journal_update, "journal=update"},
+ {Opt_journal_inum, "journal=%u"},
++ {Opt_journal_dev, "journal_dev=%u"},
+ {Opt_abort, "abort"},
+ {Opt_data_journal, "data=journal"},
+ {Opt_data_ordered, "data=ordered"},
+@@ -675,8 +677,9 @@ static unsigned long get_sb_block(void *
+ return sb_block;
+ }
+
+-static int parse_options (char * options, struct ext3_sb_info *sbi,
+- unsigned long * inum, int is_remount)
++static int parse_options (char * options, struct ext3_sb_info *sbi,
++ unsigned long *inum, unsigned long *journal_devnum,
++ int is_remount)
+ {
+ char * p;
+ substring_t args[MAX_OPT_ARGS];
+@@ -816,6 +819,16 @@ static int parse_options (char * options
+ return 0;
+ *inum = option;
+ break;
++ case Opt_journal_dev:
++ if (is_remount) {
++ printk(KERN_ERR "EXT3-fs: cannot specify "
++ "journal on remount\n");
++ return 0;
++ }
++ if (match_int(&args[0], &option))
++ return 0;
++ *journal_devnum = option;
++ break;
+ case Opt_noload:
+ set_opt (sbi->s_mount_opt, NOLOAD);
+ break;
+@@ -1278,6 +1291,7 @@ static int ext3_fill_super (struct super
+ unsigned long logic_sb_block;
+ unsigned long offset = 0;
+ unsigned long journal_inum = 0;
++ unsigned long journal_devnum = 0;
+ unsigned long def_mount_opts;
+ struct inode *root;
+ int blocksize;
+@@ -1361,7 +1375,8 @@ static int ext3_fill_super (struct super
+ if (!flush_barriers_disabled())
+ set_opt(sbi->s_mount_opt, BARRIER);
+
+- if (!parse_options ((char *) data, sbi, &journal_inum, 0))
++ if (!parse_options ((char *) data, sbi, &journal_inum, &journal_devnum,
++ 0))
+ goto failed_mount;
+
+ sb->s_flags |= MS_ONE_SECOND;
+@@ -1567,7 +1582,7 @@ static int ext3_fill_super (struct super
+ */
+ if (!test_opt(sb, NOLOAD) &&
+ EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
+- if (ext3_load_journal(sb, es))
++ if (ext3_load_journal(sb, es, journal_devnum))
+ goto failed_mount2;
+ } else if (journal_inum) {
+ if (ext3_create_journal(sb, es, journal_inum))
+@@ -1831,15 +1846,24 @@ out_bdev:
+ return NULL;
+ }
+
+-static int ext3_load_journal(struct super_block * sb,
+- struct ext3_super_block * es)
++static int ext3_load_journal(struct super_block *sb,
++ struct ext3_super_block *es,
++ unsigned long journal_devnum)
+ {
+ journal_t *journal;
+ int journal_inum = le32_to_cpu(es->s_journal_inum);
+- dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
++ dev_t journal_dev;
+ int err = 0;
+ int really_read_only;
+
++ if (journal_devnum &&
++ journal_devnum != le32_to_cpu(es->s_journal_dev)) {
++ printk(KERN_INFO "EXT3-fs: external journal device major/minor "
++ "numbers have changed\n");
++ journal_dev = new_decode_dev(journal_devnum);
++ } else
++ journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
++
+ really_read_only = bdev_read_only(sb->s_bdev);
+
+ /*
+@@ -1898,6 +1922,16 @@ static int ext3_load_journal(struct supe
+
+ EXT3_SB(sb)->s_journal = journal;
+ ext3_clear_journal_err(sb, es);
++
++ if (journal_devnum &&
++ journal_devnum != le32_to_cpu(es->s_journal_dev)) {
++ es->s_journal_dev = cpu_to_le32(journal_devnum);
++ sb->s_dirt = 1;
++
++ /* Make sure we flush the recovery flag to disk. */
++ ext3_commit_super(sb, es, 1);
++ }
++
+ return 0;
+ }
+
+@@ -2105,13 +2139,13 @@ int ext3_remount (struct super_block * s
+ {
+ struct ext3_super_block * es;
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
+- unsigned long tmp;
++ unsigned long tmp1, tmp2;
+
+ /*
+ * Allow the "check" option to be passed as a remount option.
+ */
+- if (!parse_options(data, sbi, &tmp, 1))
++ if (!parse_options(data, sbi, &tmp1, &tmp2, 1))
+ return -EINVAL;
+
+ if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)