|
@@ -27,6 +27,7 @@
|
|
|
#include <linux/seq_file.h>
|
|
|
#include <linux/log2.h>
|
|
|
#include <linux/cleancache.h>
|
|
|
+#include <linux/namei.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
|
|
|
@@ -819,6 +820,7 @@ enum {
|
|
|
Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
|
|
|
Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
|
|
|
Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
|
|
|
+ Opt_journal_path,
|
|
|
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
|
|
|
Opt_data_err_abort, Opt_data_err_ignore,
|
|
|
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
|
|
@@ -860,6 +862,7 @@ static const match_table_t tokens = {
|
|
|
{Opt_journal_update, "journal=update"},
|
|
|
{Opt_journal_inum, "journal=%u"},
|
|
|
{Opt_journal_dev, "journal_dev=%u"},
|
|
|
+ {Opt_journal_path, "journal_path=%s"},
|
|
|
{Opt_abort, "abort"},
|
|
|
{Opt_data_journal, "data=journal"},
|
|
|
{Opt_data_ordered, "data=ordered"},
|
|
@@ -975,6 +978,11 @@ static int parse_options (char *options, struct super_block *sb,
|
|
|
int option;
|
|
|
kuid_t uid;
|
|
|
kgid_t gid;
|
|
|
+ char *journal_path;
|
|
|
+ struct inode *journal_inode;
|
|
|
+ struct path path;
|
|
|
+ int error;
|
|
|
+
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
int qfmt;
|
|
|
#endif
|
|
@@ -1129,6 +1137,41 @@ static int parse_options (char *options, struct super_block *sb,
|
|
|
return 0;
|
|
|
*journal_devnum = option;
|
|
|
break;
|
|
|
+ case Opt_journal_path:
|
|
|
+ if (is_remount) {
|
|
|
+ ext3_msg(sb, KERN_ERR, "error: cannot specify "
|
|
|
+ "journal on remount");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ journal_path = match_strdup(&args[0]);
|
|
|
+ if (!journal_path) {
|
|
|
+ ext3_msg(sb, KERN_ERR, "error: could not dup "
|
|
|
+ "journal device string");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ error = kern_path(journal_path, LOOKUP_FOLLOW, &path);
|
|
|
+ if (error) {
|
|
|
+ ext3_msg(sb, KERN_ERR, "error: could not find "
|
|
|
+ "journal device path: error %d", error);
|
|
|
+ kfree(journal_path);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ journal_inode = path.dentry->d_inode;
|
|
|
+ if (!S_ISBLK(journal_inode->i_mode)) {
|
|
|
+ ext3_msg(sb, KERN_ERR, "error: journal path %s "
|
|
|
+ "is not a block device", journal_path);
|
|
|
+ path_put(&path);
|
|
|
+ kfree(journal_path);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ *journal_devnum = new_encode_dev(journal_inode->i_rdev);
|
|
|
+ path_put(&path);
|
|
|
+ kfree(journal_path);
|
|
|
+ break;
|
|
|
case Opt_noload:
|
|
|
set_opt (sbi->s_mount_opt, NOLOAD);
|
|
|
break;
|