Commit b3881f74 authored by Theodore Ts'o's avatar Theodore Ts'o

ext4: Add mount option to set kjournald's I/O priority

Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Cc: Jens Axboe <jens.axboe@oracle.com>
parent 40a1984d
...@@ -308,6 +308,13 @@ min_batch_time=usec This parameter sets the commit time (as ...@@ -308,6 +308,13 @@ min_batch_time=usec This parameter sets the commit time (as
multi-threaded, synchronous workloads on very multi-threaded, synchronous workloads on very
fast disks, at the cost of increasing latency. fast disks, at the cost of increasing latency.
journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the
highest priorty) which should be used for I/O
operations submitted by kjournald2 during a
commit operation. This defaults to 3, which is
a slightly higher priority than the default I/O
priority.
Data Mode Data Mode
========= =========
There are 3 different data modes: There are 3 different data modes:
......
...@@ -1013,7 +1013,7 @@ enum { ...@@ -1013,7 +1013,7 @@ enum {
Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_stripe, Opt_delalloc, Opt_nodelalloc,
Opt_inode_readahead_blks Opt_inode_readahead_blks, Opt_journal_ioprio
}; };
static const match_table_t tokens = { static const match_table_t tokens = {
...@@ -1074,6 +1074,7 @@ static const match_table_t tokens = { ...@@ -1074,6 +1074,7 @@ static const match_table_t tokens = {
{Opt_delalloc, "delalloc"}, {Opt_delalloc, "delalloc"},
{Opt_nodelalloc, "nodelalloc"}, {Opt_nodelalloc, "nodelalloc"},
{Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
{Opt_journal_ioprio, "journal_ioprio=%u"},
{Opt_err, NULL}, {Opt_err, NULL},
}; };
...@@ -1098,8 +1099,11 @@ static ext4_fsblk_t get_sb_block(void **data) ...@@ -1098,8 +1099,11 @@ static ext4_fsblk_t get_sb_block(void **data)
return sb_block; return sb_block;
} }
#define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3))
static int parse_options(char *options, struct super_block *sb, static int parse_options(char *options, struct super_block *sb,
unsigned long *journal_devnum, unsigned long *journal_devnum,
unsigned int *journal_ioprio,
ext4_fsblk_t *n_blocks_count, int is_remount) ext4_fsblk_t *n_blocks_count, int is_remount)
{ {
struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_sb_info *sbi = EXT4_SB(sb);
...@@ -1492,6 +1496,14 @@ static int parse_options(char *options, struct super_block *sb, ...@@ -1492,6 +1496,14 @@ static int parse_options(char *options, struct super_block *sb,
return 0; return 0;
sbi->s_inode_readahead_blks = option; sbi->s_inode_readahead_blks = option;
break; break;
case Opt_journal_ioprio:
if (match_int(&args[0], &option))
return 0;
if (option < 0 || option > 7)
break;
*journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE,
option);
break;
default: default:
printk(KERN_ERR printk(KERN_ERR
"EXT4-fs: Unrecognized mount option \"%s\" " "EXT4-fs: Unrecognized mount option \"%s\" "
...@@ -2035,6 +2047,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2035,6 +2047,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
int features; int features;
__u64 blocks_count; __u64 blocks_count;
int err; int err;
unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi)
...@@ -2141,7 +2154,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2141,7 +2154,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
set_opt(sbi->s_mount_opt, DELALLOC); set_opt(sbi->s_mount_opt, DELALLOC);
if (!parse_options((char *) data, sb, &journal_devnum, NULL, 0)) if (!parse_options((char *) data, sb, &journal_devnum,
&journal_ioprio, NULL, 0))
goto failed_mount; goto failed_mount;
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
...@@ -2506,6 +2520,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2506,6 +2520,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
default: default:
break; break;
} }
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
no_journal: no_journal:
...@@ -3127,6 +3142,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3127,6 +3142,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
unsigned long old_sb_flags; unsigned long old_sb_flags;
struct ext4_mount_options old_opts; struct ext4_mount_options old_opts;
ext4_group_t g; ext4_group_t g;
unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
int err; int err;
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
int i; int i;
...@@ -3145,11 +3161,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3145,11 +3161,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
for (i = 0; i < MAXQUOTAS; i++) for (i = 0; i < MAXQUOTAS; i++)
old_opts.s_qf_names[i] = sbi->s_qf_names[i]; old_opts.s_qf_names[i] = sbi->s_qf_names[i];
#endif #endif
if (sbi->s_journal && sbi->s_journal->j_task->io_context)
journal_ioprio = sbi->s_journal->j_task->io_context->ioprio;
/* /*
* Allow the "check" option to be passed as a remount option. * 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, &journal_ioprio,
&n_blocks_count, 1)) {
err = -EINVAL; err = -EINVAL;
goto restore_opts; goto restore_opts;
} }
...@@ -3162,8 +3181,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3162,8 +3181,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
es = sbi->s_es; es = sbi->s_es;
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);
}
if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
n_blocks_count > ext4_blocks_count(es)) { n_blocks_count > ext4_blocks_count(es)) {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/pid_namespace.h> #include <linux/pid_namespace.h>
static int set_task_ioprio(struct task_struct *task, int ioprio) int set_task_ioprio(struct task_struct *task, int ioprio)
{ {
int err; int err;
struct io_context *ioc; struct io_context *ioc;
...@@ -70,6 +70,7 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) ...@@ -70,6 +70,7 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
task_unlock(task); task_unlock(task);
return err; return err;
} }
EXPORT_SYMBOL_GPL(set_task_ioprio);
asmlinkage long sys_ioprio_set(int which, int who, int ioprio) asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
{ {
......
...@@ -86,4 +86,6 @@ static inline int task_nice_ioclass(struct task_struct *task) ...@@ -86,4 +86,6 @@ static inline int task_nice_ioclass(struct task_struct *task)
*/ */
extern int ioprio_best(unsigned short aprio, unsigned short bprio); extern int ioprio_best(unsigned short aprio, unsigned short bprio);
extern int set_task_ioprio(struct task_struct *task, int ioprio);
#endif #endif
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