[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: Johann Lombardi <johann.lombardi@bull.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
bf066c7db7
commit
71b9625744
@ -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
|
||||
|
@ -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"},
|
||||
@ -705,8 +707,9 @@ static unsigned long get_sb_block(void **data)
|
||||
return sb_block;
|
||||
}
|
||||
|
||||
static int parse_options (char * options, struct super_block *sb,
|
||||
unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
|
||||
static int parse_options (char *options, struct super_block *sb,
|
||||
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))
|
||||
@ -1902,15 +1917,24 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
|
||||
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);
|
||||
|
||||
/*
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user