Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71b96257 authored by Johann Lombardi's avatar Johann Lombardi Committed by Linus Torvalds
Browse files

[PATCH] ext3: external journal device as a mount option



The patch below adds a new mount option to allow the external journal
device to be specified.

The syntax is as follows:
# mount -t ext3 -o journal_dev=0x0820 ...
where 0x0820 means major=8 and minor=32.

Signed-off-by: default avatarJohann Lombardi <johann.lombardi@bull.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bf066c7d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,11 @@ journal=inum When a journal already exists, this option is
			the inode which will represent the ext3 file
			system's journal file.

journal_dev=devnum	When the external journal device's major/minor numbers
			have changed, this option allows to specify the new
			journal location. The journal device is identified
			through its new major/minor numbers encoded in devnum.

noload			Don't load the journal on mounting.

data=journal		All data are committed into the journal prior
+44 −10
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@
#include "acl.h"
#include "namei.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);
static void ext3_commit_super (struct super_block * sb,
@@ -628,7 +629,7 @@ enum {
	Opt_nouid32, 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_nobh,
	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_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
@@ -666,6 +667,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"},
@@ -706,7 +708,8 @@ static unsigned long get_sb_block(void **data)
}

static int parse_options (char *options, struct super_block *sb,
			  unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
			  unsigned long *inum, unsigned long *journal_devnum,
			  unsigned long *n_blocks_count, int is_remount)
{
	struct ext3_sb_info *sbi = EXT3_SB(sb);
	char * p;
@@ -839,6 +842,16 @@ static int parse_options (char * options, struct super_block *sb,
				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;
@@ -1331,6 +1344,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
	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;
@@ -1411,7 +1425,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)

	set_opt(sbi->s_mount_opt, RESERVATION);

	if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
	if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
			    NULL, 0))
		goto failed_mount;

	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
@@ -1622,7 +1637,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
	 */
	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))
@@ -1903,14 +1918,23 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
}

static int ext3_load_journal(struct super_block *sb,
			     struct ext3_super_block * es)
			     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);

	/*
@@ -1969,6 +1993,16 @@ static int ext3_load_journal(struct super_block * sb,

	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;
}

@@ -2197,7 +2231,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
	/*
	 * Allow the "check" option to be passed as a remount option.
	 */
	if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) {
	if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
		err = -EINVAL;
		goto restore_opts;
	}