Commit f4033903 authored by Curt Wohlgemuth's avatar Curt Wohlgemuth Committed by Theodore Ts'o

ext4: Make the length of the mb_history file tunable

In memory-constrained systems with many partitions, the ~68K for each
partition for the mb_history buffer can be excessive.

This patch adds a new mount option, mb_history_length, as well as a
way of setting the default via a module parameter (or via a sysfs
parameter in /sys/module/ext4/parameter/default_mb_history_length).
If the mb_history_length is set to zero, the mb_history facility is
disabled entirely.
Signed-off-by: default avatarCurt Wohlgemuth <curtw@google.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent bb23c20a
...@@ -2413,7 +2413,8 @@ static void ext4_mb_history_release(struct super_block *sb) ...@@ -2413,7 +2413,8 @@ static void ext4_mb_history_release(struct super_block *sb)
if (sbi->s_proc != NULL) { if (sbi->s_proc != NULL) {
remove_proc_entry("mb_groups", sbi->s_proc); remove_proc_entry("mb_groups", sbi->s_proc);
remove_proc_entry("mb_history", sbi->s_proc); if (sbi->s_mb_history_max)
remove_proc_entry("mb_history", sbi->s_proc);
} }
kfree(sbi->s_mb_history); kfree(sbi->s_mb_history);
} }
...@@ -2424,17 +2425,17 @@ static void ext4_mb_history_init(struct super_block *sb) ...@@ -2424,17 +2425,17 @@ static void ext4_mb_history_init(struct super_block *sb)
int i; int i;
if (sbi->s_proc != NULL) { if (sbi->s_proc != NULL) {
proc_create_data("mb_history", S_IRUGO, sbi->s_proc, if (sbi->s_mb_history_max)
&ext4_mb_seq_history_fops, sb); proc_create_data("mb_history", S_IRUGO, sbi->s_proc,
&ext4_mb_seq_history_fops, sb);
proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
&ext4_mb_seq_groups_fops, sb); &ext4_mb_seq_groups_fops, sb);
} }
sbi->s_mb_history_max = 1000;
sbi->s_mb_history_cur = 0; sbi->s_mb_history_cur = 0;
spin_lock_init(&sbi->s_mb_history_lock); spin_lock_init(&sbi->s_mb_history_lock);
i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history);
sbi->s_mb_history = kzalloc(i, GFP_KERNEL); sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL;
/* if we can't allocate history, then we simple won't use it */ /* if we can't allocate history, then we simple won't use it */
} }
...@@ -2444,7 +2445,7 @@ ext4_mb_store_history(struct ext4_allocation_context *ac) ...@@ -2444,7 +2445,7 @@ ext4_mb_store_history(struct ext4_allocation_context *ac)
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
struct ext4_mb_history h; struct ext4_mb_history h;
if (unlikely(sbi->s_mb_history == NULL)) if (sbi->s_mb_history == NULL)
return; return;
if (!(ac->ac_op & sbi->s_mb_history_filter)) if (!(ac->ac_op & sbi->s_mb_history_filter))
......
...@@ -47,6 +47,13 @@ ...@@ -47,6 +47,13 @@
#include "xattr.h" #include "xattr.h"
#include "acl.h" #include "acl.h"
static int default_mb_history_length = 1000;
module_param_named(default_mb_history_length, default_mb_history_length,
int, 0644);
MODULE_PARM_DESC(default_mb_history_length,
"Default number of entries saved for mb_history");
struct proc_dir_entry *ext4_proc_root; struct proc_dir_entry *ext4_proc_root;
static struct kset *ext4_kset; static struct kset *ext4_kset;
...@@ -1042,7 +1049,7 @@ enum { ...@@ -1042,7 +1049,7 @@ enum {
Opt_journal_update, Opt_journal_dev, Opt_journal_update, Opt_journal_dev,
Opt_journal_checksum, Opt_journal_async_commit, Opt_journal_checksum, Opt_journal_async_commit,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_data_err_abort, Opt_data_err_ignore, Opt_data_err_abort, Opt_data_err_ignore, Opt_mb_history_length,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
...@@ -1088,6 +1095,7 @@ static const match_table_t tokens = { ...@@ -1088,6 +1095,7 @@ static const match_table_t tokens = {
{Opt_data_writeback, "data=writeback"}, {Opt_data_writeback, "data=writeback"},
{Opt_data_err_abort, "data_err=abort"}, {Opt_data_err_abort, "data_err=abort"},
{Opt_data_err_ignore, "data_err=ignore"}, {Opt_data_err_ignore, "data_err=ignore"},
{Opt_mb_history_length, "mb_history_length=%u"},
{Opt_offusrjquota, "usrjquota="}, {Opt_offusrjquota, "usrjquota="},
{Opt_usrjquota, "usrjquota=%s"}, {Opt_usrjquota, "usrjquota=%s"},
{Opt_offgrpjquota, "grpjquota="}, {Opt_offgrpjquota, "grpjquota="},
...@@ -1329,6 +1337,13 @@ static int parse_options(char *options, struct super_block *sb, ...@@ -1329,6 +1337,13 @@ static int parse_options(char *options, struct super_block *sb,
case Opt_data_err_ignore: case Opt_data_err_ignore:
clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
break; break;
case Opt_mb_history_length:
if (match_int(&args[0], &option))
return 0;
if (option < 0)
return 0;
sbi->s_mb_history_max = option;
break;
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
case Opt_usrjquota: case Opt_usrjquota:
qtype = USRQUOTA; qtype = USRQUOTA;
...@@ -2345,6 +2360,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2345,6 +2360,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ;
sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
sbi->s_mb_history_max = default_mb_history_length;
set_opt(sbi->s_mount_opt, BARRIER); set_opt(sbi->s_mount_opt, BARRIER);
......
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