Commit b237e304 authored by Harshad Shirwadkar's avatar Harshad Shirwadkar Committed by Theodore Ts'o

ext4: add ability to return parsed options from parse_options

Before this patch, the function parse_options() was returning
journal_devnum and journal_ioprio variables to the caller. This patch
generalizes that interface to allow parse_options to return any parsed
options to return back to the caller. In this patch series, it gets
used to capture the value of "mb_optimize_scan=%u" mount option.
Signed-off-by: default avatarHarshad Shirwadkar <harshadshirwadkar@gmail.com>
Reviewed-by: default avatarRitesh Harjani <ritesh.list@gmail.com>
Link: https://lore.kernel.org/r/20210401172129.189766-3-harshadshirwadkar@gmail.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 67d25186
...@@ -2090,9 +2090,14 @@ static int ext4_set_test_dummy_encryption(struct super_block *sb, ...@@ -2090,9 +2090,14 @@ static int ext4_set_test_dummy_encryption(struct super_block *sb,
return 1; return 1;
} }
struct ext4_parsed_options {
unsigned long journal_devnum;
unsigned int journal_ioprio;
};
static int handle_mount_opt(struct super_block *sb, char *opt, int token, static int handle_mount_opt(struct super_block *sb, char *opt, int token,
substring_t *args, unsigned long *journal_devnum, substring_t *args, struct ext4_parsed_options *parsed_opts,
unsigned int *journal_ioprio, int is_remount) int is_remount)
{ {
struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_sb_info *sbi = EXT4_SB(sb);
const struct mount_opts *m; const struct mount_opts *m;
...@@ -2249,7 +2254,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, ...@@ -2249,7 +2254,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
"Cannot specify journal on remount"); "Cannot specify journal on remount");
return -1; return -1;
} }
*journal_devnum = arg; parsed_opts->journal_devnum = arg;
} else if (token == Opt_journal_path) { } else if (token == Opt_journal_path) {
char *journal_path; char *journal_path;
struct inode *journal_inode; struct inode *journal_inode;
...@@ -2285,7 +2290,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, ...@@ -2285,7 +2290,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
return -1; return -1;
} }
*journal_devnum = new_encode_dev(journal_inode->i_rdev); parsed_opts->journal_devnum = new_encode_dev(journal_inode->i_rdev);
path_put(&path); path_put(&path);
kfree(journal_path); kfree(journal_path);
} else if (token == Opt_journal_ioprio) { } else if (token == Opt_journal_ioprio) {
...@@ -2294,7 +2299,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, ...@@ -2294,7 +2299,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
" (must be 0-7)"); " (must be 0-7)");
return -1; return -1;
} }
*journal_ioprio = parsed_opts->journal_ioprio =
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg); IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
} else if (token == Opt_test_dummy_encryption) { } else if (token == Opt_test_dummy_encryption) {
return ext4_set_test_dummy_encryption(sb, opt, &args[0], return ext4_set_test_dummy_encryption(sb, opt, &args[0],
...@@ -2411,8 +2416,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, ...@@ -2411,8 +2416,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
} }
static int parse_options(char *options, struct super_block *sb, static int parse_options(char *options, struct super_block *sb,
unsigned long *journal_devnum, struct ext4_parsed_options *ret_opts,
unsigned int *journal_ioprio,
int is_remount) int is_remount)
{ {
struct ext4_sb_info __maybe_unused *sbi = EXT4_SB(sb); struct ext4_sb_info __maybe_unused *sbi = EXT4_SB(sb);
...@@ -2432,8 +2436,8 @@ static int parse_options(char *options, struct super_block *sb, ...@@ -2432,8 +2436,8 @@ static int parse_options(char *options, struct super_block *sb,
*/ */
args[0].to = args[0].from = NULL; args[0].to = args[0].from = NULL;
token = match_token(p, tokens, args); token = match_token(p, tokens, args);
if (handle_mount_opt(sb, p, token, args, journal_devnum, if (handle_mount_opt(sb, p, token, args, ret_opts,
journal_ioprio, is_remount) < 0) is_remount) < 0)
return 0; return 0;
} }
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
...@@ -4015,7 +4019,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4015,7 +4019,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
ext4_fsblk_t sb_block = get_sb_block(&data); ext4_fsblk_t sb_block = get_sb_block(&data);
ext4_fsblk_t logical_sb_block; ext4_fsblk_t logical_sb_block;
unsigned long offset = 0; unsigned long offset = 0;
unsigned long journal_devnum = 0;
unsigned long def_mount_opts; unsigned long def_mount_opts;
struct inode *root; struct inode *root;
const char *descr; const char *descr;
...@@ -4026,8 +4029,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4026,8 +4029,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
int needs_recovery, has_huge_files; int needs_recovery, has_huge_files;
__u64 blocks_count; __u64 blocks_count;
int err = 0; int err = 0;
unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
ext4_group_t first_not_zeroed; ext4_group_t first_not_zeroed;
struct ext4_parsed_options parsed_opts;
/* Set defaults for the variables that will be set during parsing */
parsed_opts.journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
parsed_opts.journal_devnum = 0;
if ((data && !orig_data) || !sbi) if ((data && !orig_data) || !sbi)
goto out_free_base; goto out_free_base;
...@@ -4273,8 +4280,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4273,8 +4280,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
GFP_KERNEL); GFP_KERNEL);
if (!s_mount_opts) if (!s_mount_opts)
goto failed_mount; goto failed_mount;
if (!parse_options(s_mount_opts, sb, &journal_devnum, if (!parse_options(s_mount_opts, sb, &parsed_opts, 0)) {
&journal_ioprio, 0)) {
ext4_msg(sb, KERN_WARNING, ext4_msg(sb, KERN_WARNING,
"failed to parse options in superblock: %s", "failed to parse options in superblock: %s",
s_mount_opts); s_mount_opts);
...@@ -4282,8 +4288,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4282,8 +4288,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
kfree(s_mount_opts); kfree(s_mount_opts);
} }
sbi->s_def_mount_opt = sbi->s_mount_opt; sbi->s_def_mount_opt = sbi->s_mount_opt;
if (!parse_options((char *) data, sb, &journal_devnum, if (!parse_options((char *) data, sb, &parsed_opts, 0))
&journal_ioprio, 0))
goto failed_mount; goto failed_mount;
#ifdef CONFIG_UNICODE #ifdef CONFIG_UNICODE
...@@ -4768,7 +4773,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4768,7 +4773,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
* root first: it may be modified in the journal! * root first: it may be modified in the journal!
*/ */
if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) { if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
err = ext4_load_journal(sb, es, journal_devnum); err = ext4_load_journal(sb, es, parsed_opts.journal_devnum);
if (err) if (err)
goto failed_mount3a; goto failed_mount3a;
} else if (test_opt(sb, NOLOAD) && !sb_rdonly(sb) && } else if (test_opt(sb, NOLOAD) && !sb_rdonly(sb) &&
...@@ -4868,7 +4873,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4868,7 +4873,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount_wq; goto failed_mount_wq;
} }
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); set_task_ioprio(sbi->s_journal->j_task, parsed_opts.journal_ioprio);
sbi->s_journal->j_submit_inode_data_buffers = sbi->s_journal->j_submit_inode_data_buffers =
ext4_journal_submit_inode_data_buffers; ext4_journal_submit_inode_data_buffers;
...@@ -5807,13 +5812,16 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -5807,13 +5812,16 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
struct ext4_mount_options old_opts; struct ext4_mount_options old_opts;
int enable_quota = 0; int enable_quota = 0;
ext4_group_t g; ext4_group_t g;
unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
int err = 0; int err = 0;
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
int i, j; int i, j;
char *to_free[EXT4_MAXQUOTAS]; char *to_free[EXT4_MAXQUOTAS];
#endif #endif
char *orig_data = kstrdup(data, GFP_KERNEL); char *orig_data = kstrdup(data, GFP_KERNEL);
struct ext4_parsed_options parsed_opts;
parsed_opts.journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
parsed_opts.journal_devnum = 0;
if (data && !orig_data) if (data && !orig_data)
return -ENOMEM; return -ENOMEM;
...@@ -5844,7 +5852,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -5844,7 +5852,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
old_opts.s_qf_names[i] = NULL; old_opts.s_qf_names[i] = NULL;
#endif #endif
if (sbi->s_journal && sbi->s_journal->j_task->io_context) if (sbi->s_journal && sbi->s_journal->j_task->io_context)
journal_ioprio = sbi->s_journal->j_task->io_context->ioprio; parsed_opts.journal_ioprio =
sbi->s_journal->j_task->io_context->ioprio;
/* /*
* Some options can be enabled by ext4 and/or by VFS mount flag * Some options can be enabled by ext4 and/or by VFS mount flag
...@@ -5854,7 +5863,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -5854,7 +5863,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
vfs_flags = SB_LAZYTIME | SB_I_VERSION; vfs_flags = SB_LAZYTIME | SB_I_VERSION;
sb->s_flags = (sb->s_flags & ~vfs_flags) | (*flags & vfs_flags); sb->s_flags = (sb->s_flags & ~vfs_flags) | (*flags & vfs_flags);
if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) { if (!parse_options(data, sb, &parsed_opts, 1)) {
err = -EINVAL; err = -EINVAL;
goto restore_opts; goto restore_opts;
} }
...@@ -5904,7 +5913,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -5904,7 +5913,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
if (sbi->s_journal) { if (sbi->s_journal) {
ext4_init_journal_params(sb, sbi->s_journal); ext4_init_journal_params(sb, sbi->s_journal);
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); set_task_ioprio(sbi->s_journal->j_task, parsed_opts.journal_ioprio);
} }
/* Flush outstanding errors before changing fs state */ /* Flush outstanding errors before changing fs state */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment