diff options
-rw-r--r-- | Documentation/filesystems/ext4.txt | 7 | ||||
-rw-r--r-- | fs/ext4/super.c | 29 | ||||
-rw-r--r-- | fs/ioprio.c | 3 | ||||
-rw-r--r-- | include/linux/ioprio.h | 2 |
4 files changed, 36 insertions, 5 deletions
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index 9ec29d86ff8b..8938949b201e 100644 --- a/Documentation/filesystems/ext4.txt +++ b/Documentation/filesystems/ext4.txt | |||
@@ -308,6 +308,13 @@ min_batch_time=usec This parameter sets the commit time (as | |||
308 | multi-threaded, synchronous workloads on very | 308 | multi-threaded, synchronous workloads on very |
309 | fast disks, at the cost of increasing latency. | 309 | fast disks, at the cost of increasing latency. |
310 | 310 | ||
311 | journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the | ||
312 | highest priorty) which should be used for I/O | ||
313 | operations submitted by kjournald2 during a | ||
314 | commit operation. This defaults to 3, which is | ||
315 | a slightly higher priority than the default I/O | ||
316 | priority. | ||
317 | |||
311 | Data Mode | 318 | Data Mode |
312 | ========= | 319 | ========= |
313 | There are 3 different data modes: | 320 | There are 3 different data modes: |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8036392b2121..8ff8709828fd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1013,7 +1013,7 @@ enum { | |||
1013 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 1013 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
1014 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, | 1014 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, |
1015 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1015 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
1016 | Opt_inode_readahead_blks | 1016 | Opt_inode_readahead_blks, Opt_journal_ioprio |
1017 | }; | 1017 | }; |
1018 | 1018 | ||
1019 | static const match_table_t tokens = { | 1019 | static const match_table_t tokens = { |
@@ -1074,6 +1074,7 @@ static const match_table_t tokens = { | |||
1074 | {Opt_delalloc, "delalloc"}, | 1074 | {Opt_delalloc, "delalloc"}, |
1075 | {Opt_nodelalloc, "nodelalloc"}, | 1075 | {Opt_nodelalloc, "nodelalloc"}, |
1076 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | 1076 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
1077 | {Opt_journal_ioprio, "journal_ioprio=%u"}, | ||
1077 | {Opt_err, NULL}, | 1078 | {Opt_err, NULL}, |
1078 | }; | 1079 | }; |
1079 | 1080 | ||
@@ -1098,8 +1099,11 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
1098 | return sb_block; | 1099 | return sb_block; |
1099 | } | 1100 | } |
1100 | 1101 | ||
1102 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) | ||
1103 | |||
1101 | static int parse_options(char *options, struct super_block *sb, | 1104 | static int parse_options(char *options, struct super_block *sb, |
1102 | unsigned long *journal_devnum, | 1105 | unsigned long *journal_devnum, |
1106 | unsigned int *journal_ioprio, | ||
1103 | ext4_fsblk_t *n_blocks_count, int is_remount) | 1107 | ext4_fsblk_t *n_blocks_count, int is_remount) |
1104 | { | 1108 | { |
1105 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1109 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
@@ -1492,6 +1496,14 @@ set_qf_format: | |||
1492 | return 0; | 1496 | return 0; |
1493 | sbi->s_inode_readahead_blks = option; | 1497 | sbi->s_inode_readahead_blks = option; |
1494 | break; | 1498 | break; |
1499 | case Opt_journal_ioprio: | ||
1500 | if (match_int(&args[0], &option)) | ||
1501 | return 0; | ||
1502 | if (option < 0 || option > 7) | ||
1503 | break; | ||
1504 | *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, | ||
1505 | option); | ||
1506 | break; | ||
1495 | default: | 1507 | default: |
1496 | printk(KERN_ERR | 1508 | printk(KERN_ERR |
1497 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1509 | "EXT4-fs: Unrecognized mount option \"%s\" " |
@@ -2035,6 +2047,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2035 | int features; | 2047 | int features; |
2036 | __u64 blocks_count; | 2048 | __u64 blocks_count; |
2037 | int err; | 2049 | int err; |
2050 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; | ||
2038 | 2051 | ||
2039 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 2052 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
2040 | if (!sbi) | 2053 | if (!sbi) |
@@ -2141,7 +2154,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2141 | set_opt(sbi->s_mount_opt, DELALLOC); | 2154 | set_opt(sbi->s_mount_opt, DELALLOC); |
2142 | 2155 | ||
2143 | 2156 | ||
2144 | if (!parse_options((char *) data, sb, &journal_devnum, NULL, 0)) | 2157 | if (!parse_options((char *) data, sb, &journal_devnum, |
2158 | &journal_ioprio, NULL, 0)) | ||
2145 | goto failed_mount; | 2159 | goto failed_mount; |
2146 | 2160 | ||
2147 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 2161 | 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 | default: | 2520 | default: |
2507 | break; | 2521 | break; |
2508 | } | 2522 | } |
2523 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | ||
2509 | 2524 | ||
2510 | no_journal: | 2525 | no_journal: |
2511 | 2526 | ||
@@ -3127,6 +3142,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3127 | unsigned long old_sb_flags; | 3142 | unsigned long old_sb_flags; |
3128 | struct ext4_mount_options old_opts; | 3143 | struct ext4_mount_options old_opts; |
3129 | ext4_group_t g; | 3144 | ext4_group_t g; |
3145 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; | ||
3130 | int err; | 3146 | int err; |
3131 | #ifdef CONFIG_QUOTA | 3147 | #ifdef CONFIG_QUOTA |
3132 | int i; | 3148 | int i; |
@@ -3145,11 +3161,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3145 | for (i = 0; i < MAXQUOTAS; i++) | 3161 | for (i = 0; i < MAXQUOTAS; i++) |
3146 | old_opts.s_qf_names[i] = sbi->s_qf_names[i]; | 3162 | old_opts.s_qf_names[i] = sbi->s_qf_names[i]; |
3147 | #endif | 3163 | #endif |
3164 | if (sbi->s_journal && sbi->s_journal->j_task->io_context) | ||
3165 | journal_ioprio = sbi->s_journal->j_task->io_context->ioprio; | ||
3148 | 3166 | ||
3149 | /* | 3167 | /* |
3150 | * Allow the "check" option to be passed as a remount option. | 3168 | * Allow the "check" option to be passed as a remount option. |
3151 | */ | 3169 | */ |
3152 | if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) { | 3170 | if (!parse_options(data, sb, NULL, &journal_ioprio, |
3171 | &n_blocks_count, 1)) { | ||
3153 | err = -EINVAL; | 3172 | err = -EINVAL; |
3154 | goto restore_opts; | 3173 | goto restore_opts; |
3155 | } | 3174 | } |
@@ -3162,8 +3181,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3162 | 3181 | ||
3163 | es = sbi->s_es; | 3182 | es = sbi->s_es; |
3164 | 3183 | ||
3165 | if (sbi->s_journal) | 3184 | if (sbi->s_journal) { |
3166 | ext4_init_journal_params(sb, sbi->s_journal); | 3185 | ext4_init_journal_params(sb, sbi->s_journal); |
3186 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | ||
3187 | } | ||
3167 | 3188 | ||
3168 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || | 3189 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || |
3169 | n_blocks_count > ext4_blocks_count(es)) { | 3190 | n_blocks_count > ext4_blocks_count(es)) { |
diff --git a/fs/ioprio.c b/fs/ioprio.c index 3569e0ad86a2..1a39ac370942 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/security.h> | 27 | #include <linux/security.h> |
28 | #include <linux/pid_namespace.h> | 28 | #include <linux/pid_namespace.h> |
29 | 29 | ||
30 | static int set_task_ioprio(struct task_struct *task, int ioprio) | 30 | int set_task_ioprio(struct task_struct *task, int ioprio) |
31 | { | 31 | { |
32 | int err; | 32 | int err; |
33 | struct io_context *ioc; | 33 | struct io_context *ioc; |
@@ -70,6 +70,7 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) | |||
70 | task_unlock(task); | 70 | task_unlock(task); |
71 | return err; | 71 | return err; |
72 | } | 72 | } |
73 | EXPORT_SYMBOL_GPL(set_task_ioprio); | ||
73 | 74 | ||
74 | asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | 75 | asmlinkage long sys_ioprio_set(int which, int who, int ioprio) |
75 | { | 76 | { |
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h index f98a656b17e5..76dad4808847 100644 --- a/include/linux/ioprio.h +++ b/include/linux/ioprio.h | |||
@@ -86,4 +86,6 @@ static inline int task_nice_ioclass(struct task_struct *task) | |||
86 | */ | 86 | */ |
87 | extern int ioprio_best(unsigned short aprio, unsigned short bprio); | 87 | extern int ioprio_best(unsigned short aprio, unsigned short bprio); |
88 | 88 | ||
89 | extern int set_task_ioprio(struct task_struct *task, int ioprio); | ||
90 | |||
89 | #endif | 91 | #endif |