aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2008-10-09 23:53:47 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-10-09 23:53:47 -0400
commit240799cdf22bd789ea6852653c3b879d35ad0a6c (patch)
treee696b60cc103f23838b5c14d8d397f692abffbc3 /fs/ext4/super.c
parent37515facd001942221d68171c81c1f46d54ffdd0 (diff)
ext4: Use readahead when reading an inode from the inode table
With modern hard drives, reading 64k takes roughly the same time as reading a 4k block. So request readahead for adjacent inode table blocks to reduce the time it takes when iterating over directories (especially when doing this in htree sort order) in a cold cache case. With this patch, the time it takes to run "git status" on a kernel tree after flushing the caches via "echo 3 > /proc/sys/vm/drop_caches" is reduced by 21%. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9f5468fb06da..6583aee5177f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -515,8 +515,10 @@ static void ext4_put_super(struct super_block *sb)
515 mark_buffer_dirty(sbi->s_sbh); 515 mark_buffer_dirty(sbi->s_sbh);
516 ext4_commit_super(sb, es, 1); 516 ext4_commit_super(sb, es, 1);
517 } 517 }
518 if (sbi->s_proc) 518 if (sbi->s_proc) {
519 remove_proc_entry("inode_readahead_blks", sbi->s_proc);
519 remove_proc_entry(sb->s_id, ext4_proc_root); 520 remove_proc_entry(sb->s_id, ext4_proc_root);
521 }
520 522
521 for (i = 0; i < sbi->s_gdb_count; i++) 523 for (i = 0; i < sbi->s_gdb_count; i++)
522 brelse(sbi->s_group_desc[i]); 524 brelse(sbi->s_group_desc[i]);
@@ -779,6 +781,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
779 else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) 781 else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
780 seq_puts(seq, ",data=writeback"); 782 seq_puts(seq, ",data=writeback");
781 783
784 if (sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS)
785 seq_printf(seq, ",inode_readahead_blks=%u",
786 sbi->s_inode_readahead_blks);
787
782 ext4_show_quota_options(seq, sb); 788 ext4_show_quota_options(seq, sb);
783 return 0; 789 return 0;
784} 790}
@@ -913,6 +919,7 @@ enum {
913 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, 919 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
914 Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, 920 Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
915 Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc, 921 Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc,
922 Opt_inode_readahead_blks
916}; 923};
917 924
918static match_table_t tokens = { 925static match_table_t tokens = {
@@ -973,6 +980,7 @@ static match_table_t tokens = {
973 {Opt_resize, "resize"}, 980 {Opt_resize, "resize"},
974 {Opt_delalloc, "delalloc"}, 981 {Opt_delalloc, "delalloc"},
975 {Opt_nodelalloc, "nodelalloc"}, 982 {Opt_nodelalloc, "nodelalloc"},
983 {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
976 {Opt_err, NULL}, 984 {Opt_err, NULL},
977}; 985};
978 986
@@ -1381,6 +1389,13 @@ set_qf_format:
1381 case Opt_delalloc: 1389 case Opt_delalloc:
1382 set_opt(sbi->s_mount_opt, DELALLOC); 1390 set_opt(sbi->s_mount_opt, DELALLOC);
1383 break; 1391 break;
1392 case Opt_inode_readahead_blks:
1393 if (match_int(&args[0], &option))
1394 return 0;
1395 if (option < 0 || option > (1 << 30))
1396 return 0;
1397 sbi->s_inode_readahead_blks = option;
1398 break;
1384 default: 1399 default:
1385 printk(KERN_ERR 1400 printk(KERN_ERR
1386 "EXT4-fs: Unrecognized mount option \"%s\" " 1401 "EXT4-fs: Unrecognized mount option \"%s\" "
@@ -1938,6 +1953,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
1938 sbi->s_mount_opt = 0; 1953 sbi->s_mount_opt = 0;
1939 sbi->s_resuid = EXT4_DEF_RESUID; 1954 sbi->s_resuid = EXT4_DEF_RESUID;
1940 sbi->s_resgid = EXT4_DEF_RESGID; 1955 sbi->s_resgid = EXT4_DEF_RESGID;
1956 sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS;
1941 sbi->s_sb_block = sb_block; 1957 sbi->s_sb_block = sb_block;
1942 1958
1943 unlock_kernel(); 1959 unlock_kernel();
@@ -2234,6 +2250,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2234 if (ext4_proc_root) 2250 if (ext4_proc_root)
2235 sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); 2251 sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
2236 2252
2253 if (sbi->s_proc)
2254 proc_create_data("inode_readahead_blks", 0644, sbi->s_proc,
2255 &ext4_ui_proc_fops,
2256 &sbi->s_inode_readahead_blks);
2257
2237 bgl_lock_init(&sbi->s_blockgroup_lock); 2258 bgl_lock_init(&sbi->s_blockgroup_lock);
2238 2259
2239 for (i = 0; i < db_count; i++) { 2260 for (i = 0; i < db_count; i++) {
@@ -2513,8 +2534,10 @@ failed_mount2:
2513 brelse(sbi->s_group_desc[i]); 2534 brelse(sbi->s_group_desc[i]);
2514 kfree(sbi->s_group_desc); 2535 kfree(sbi->s_group_desc);
2515failed_mount: 2536failed_mount:
2516 if (sbi->s_proc) 2537 if (sbi->s_proc) {
2538 remove_proc_entry("inode_readahead_blks", sbi->s_proc);
2517 remove_proc_entry(sb->s_id, ext4_proc_root); 2539 remove_proc_entry(sb->s_id, ext4_proc_root);
2540 }
2518#ifdef CONFIG_QUOTA 2541#ifdef CONFIG_QUOTA
2519 for (i = 0; i < MAXQUOTAS; i++) 2542 for (i = 0; i < MAXQUOTAS; i++)
2520 kfree(sbi->s_qf_names[i]); 2543 kfree(sbi->s_qf_names[i]);