diff options
author | Curt Wohlgemuth <curtw@google.com> | 2009-05-01 20:27:20 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-05-01 20:27:20 -0400 |
commit | f40339031b04279c3fdde7ac5fe97db33b2a7694 (patch) | |
tree | 62b565c12488c63e620e5686304c16ed3434b735 | |
parent | bb23c20a851a5038b255a3c0d0aa56093c1da3f8 (diff) |
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: Curt Wohlgemuth <curtw@google.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/mballoc.c | 13 | ||||
-rw-r--r-- | fs/ext4/super.c | 18 |
2 files changed, 24 insertions, 7 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dbd47eac13ec..df75855ae6f7 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2413,7 +2413,8 @@ static void ext4_mb_history_release(struct super_block *sb) | |||
2413 | 2413 | ||
2414 | if (sbi->s_proc != NULL) { | 2414 | if (sbi->s_proc != NULL) { |
2415 | remove_proc_entry("mb_groups", sbi->s_proc); | 2415 | remove_proc_entry("mb_groups", sbi->s_proc); |
2416 | remove_proc_entry("mb_history", sbi->s_proc); | 2416 | if (sbi->s_mb_history_max) |
2417 | remove_proc_entry("mb_history", sbi->s_proc); | ||
2417 | } | 2418 | } |
2418 | kfree(sbi->s_mb_history); | 2419 | kfree(sbi->s_mb_history); |
2419 | } | 2420 | } |
@@ -2424,17 +2425,17 @@ static void ext4_mb_history_init(struct super_block *sb) | |||
2424 | int i; | 2425 | int i; |
2425 | 2426 | ||
2426 | if (sbi->s_proc != NULL) { | 2427 | if (sbi->s_proc != NULL) { |
2427 | proc_create_data("mb_history", S_IRUGO, sbi->s_proc, | 2428 | if (sbi->s_mb_history_max) |
2428 | &ext4_mb_seq_history_fops, sb); | 2429 | proc_create_data("mb_history", S_IRUGO, sbi->s_proc, |
2430 | &ext4_mb_seq_history_fops, sb); | ||
2429 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, | 2431 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, |
2430 | &ext4_mb_seq_groups_fops, sb); | 2432 | &ext4_mb_seq_groups_fops, sb); |
2431 | } | 2433 | } |
2432 | 2434 | ||
2433 | sbi->s_mb_history_max = 1000; | ||
2434 | sbi->s_mb_history_cur = 0; | 2435 | sbi->s_mb_history_cur = 0; |
2435 | spin_lock_init(&sbi->s_mb_history_lock); | 2436 | spin_lock_init(&sbi->s_mb_history_lock); |
2436 | i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); | 2437 | i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); |
2437 | sbi->s_mb_history = kzalloc(i, GFP_KERNEL); | 2438 | sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL; |
2438 | /* if we can't allocate history, then we simple won't use it */ | 2439 | /* if we can't allocate history, then we simple won't use it */ |
2439 | } | 2440 | } |
2440 | 2441 | ||
@@ -2444,7 +2445,7 @@ ext4_mb_store_history(struct ext4_allocation_context *ac) | |||
2444 | struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); | 2445 | struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); |
2445 | struct ext4_mb_history h; | 2446 | struct ext4_mb_history h; |
2446 | 2447 | ||
2447 | if (unlikely(sbi->s_mb_history == NULL)) | 2448 | if (sbi->s_mb_history == NULL) |
2448 | return; | 2449 | return; |
2449 | 2450 | ||
2450 | if (!(ac->ac_op & sbi->s_mb_history_filter)) | 2451 | if (!(ac->ac_op & sbi->s_mb_history_filter)) |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7903f20c8075..39223a52bc71 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -47,6 +47,13 @@ | |||
47 | #include "xattr.h" | 47 | #include "xattr.h" |
48 | #include "acl.h" | 48 | #include "acl.h" |
49 | 49 | ||
50 | static int default_mb_history_length = 1000; | ||
51 | |||
52 | module_param_named(default_mb_history_length, default_mb_history_length, | ||
53 | int, 0644); | ||
54 | MODULE_PARM_DESC(default_mb_history_length, | ||
55 | "Default number of entries saved for mb_history"); | ||
56 | |||
50 | struct proc_dir_entry *ext4_proc_root; | 57 | struct proc_dir_entry *ext4_proc_root; |
51 | static struct kset *ext4_kset; | 58 | static struct kset *ext4_kset; |
52 | 59 | ||
@@ -1042,7 +1049,7 @@ enum { | |||
1042 | Opt_journal_update, Opt_journal_dev, | 1049 | Opt_journal_update, Opt_journal_dev, |
1043 | Opt_journal_checksum, Opt_journal_async_commit, | 1050 | Opt_journal_checksum, Opt_journal_async_commit, |
1044 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 1051 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
1045 | Opt_data_err_abort, Opt_data_err_ignore, | 1052 | Opt_data_err_abort, Opt_data_err_ignore, Opt_mb_history_length, |
1046 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 1053 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
1047 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 1054 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
1048 | Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, | 1055 | Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, |
@@ -1088,6 +1095,7 @@ static const match_table_t tokens = { | |||
1088 | {Opt_data_writeback, "data=writeback"}, | 1095 | {Opt_data_writeback, "data=writeback"}, |
1089 | {Opt_data_err_abort, "data_err=abort"}, | 1096 | {Opt_data_err_abort, "data_err=abort"}, |
1090 | {Opt_data_err_ignore, "data_err=ignore"}, | 1097 | {Opt_data_err_ignore, "data_err=ignore"}, |
1098 | {Opt_mb_history_length, "mb_history_length=%u"}, | ||
1091 | {Opt_offusrjquota, "usrjquota="}, | 1099 | {Opt_offusrjquota, "usrjquota="}, |
1092 | {Opt_usrjquota, "usrjquota=%s"}, | 1100 | {Opt_usrjquota, "usrjquota=%s"}, |
1093 | {Opt_offgrpjquota, "grpjquota="}, | 1101 | {Opt_offgrpjquota, "grpjquota="}, |
@@ -1329,6 +1337,13 @@ static int parse_options(char *options, struct super_block *sb, | |||
1329 | case Opt_data_err_ignore: | 1337 | case Opt_data_err_ignore: |
1330 | clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); | 1338 | clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); |
1331 | break; | 1339 | break; |
1340 | case Opt_mb_history_length: | ||
1341 | if (match_int(&args[0], &option)) | ||
1342 | return 0; | ||
1343 | if (option < 0) | ||
1344 | return 0; | ||
1345 | sbi->s_mb_history_max = option; | ||
1346 | break; | ||
1332 | #ifdef CONFIG_QUOTA | 1347 | #ifdef CONFIG_QUOTA |
1333 | case Opt_usrjquota: | 1348 | case Opt_usrjquota: |
1334 | qtype = USRQUOTA; | 1349 | qtype = USRQUOTA; |
@@ -2345,6 +2360,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2345 | sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; | 2360 | sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; |
2346 | sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; | 2361 | sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; |
2347 | sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; | 2362 | sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; |
2363 | sbi->s_mb_history_max = default_mb_history_length; | ||
2348 | 2364 | ||
2349 | set_opt(sbi->s_mount_opt, BARRIER); | 2365 | set_opt(sbi->s_mount_opt, BARRIER); |
2350 | 2366 | ||