aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorJose R. Santos <jrs@us.ibm.com>2008-07-11 19:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-11 19:27:31 -0400
commit772cb7c83ba256a11c7bf99a11bef3858d23767c (patch)
treea42b97e5cbd870a76b2646c2dcb658a92c53f637 /fs/ext4/super.c
parent736603ab297506f4396cb5af592004499950fcfd (diff)
ext4: New inode allocation for FLEX_BG meta-data groups.
This patch mostly controls the way inode are allocated in order to make ialloc aware of flex_bg block group grouping. It achieves this by bypassing the Orlov allocator when block group meta-data are packed toghether through mke2fs. Since the impact on the block allocator is minimal, this patch should have little or no effect on other block allocation algorithms. By controlling the inode allocation, it can basically control where the initial search for new block begins and thus indirectly manipulate the block allocator. This allocator favors data and meta-data locality so the disk will gradually be filled from block group zero upward. This helps improve performance by reducing seek time. Since the group of inode tables within one flex_bg are treated as one giant inode table, uninitialized block groups would not need to partially initialize as many inode table as with Orlov which would help fsck time as the filesystem usage goes up. Signed-off-by: Jose R. Santos <jrs@us.ibm.com> Signed-off-by: Valerie Clement <valerie.clement@bull.net> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 588cfb408642..b9ad3d852061 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -517,6 +517,7 @@ static void ext4_put_super (struct super_block * sb)
517 for (i = 0; i < sbi->s_gdb_count; i++) 517 for (i = 0; i < sbi->s_gdb_count; i++)
518 brelse(sbi->s_group_desc[i]); 518 brelse(sbi->s_group_desc[i]);
519 kfree(sbi->s_group_desc); 519 kfree(sbi->s_group_desc);
520 kfree(sbi->s_flex_groups);
520 percpu_counter_destroy(&sbi->s_freeblocks_counter); 521 percpu_counter_destroy(&sbi->s_freeblocks_counter);
521 percpu_counter_destroy(&sbi->s_freeinodes_counter); 522 percpu_counter_destroy(&sbi->s_freeinodes_counter);
522 percpu_counter_destroy(&sbi->s_dirs_counter); 523 percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -1442,6 +1443,54 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1442 return res; 1443 return res;
1443} 1444}
1444 1445
1446static int ext4_fill_flex_info(struct super_block *sb)
1447{
1448 struct ext4_sb_info *sbi = EXT4_SB(sb);
1449 struct ext4_group_desc *gdp = NULL;
1450 struct buffer_head *bh;
1451 ext4_group_t flex_group_count;
1452 ext4_group_t flex_group;
1453 int groups_per_flex = 0;
1454 __u64 block_bitmap = 0;
1455 int i;
1456
1457 if (!sbi->s_es->s_log_groups_per_flex) {
1458 sbi->s_log_groups_per_flex = 0;
1459 return 1;
1460 }
1461
1462 sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
1463 groups_per_flex = 1 << sbi->s_log_groups_per_flex;
1464
1465 flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) /
1466 groups_per_flex;
1467 sbi->s_flex_groups = kmalloc(flex_group_count *
1468 sizeof(struct flex_groups), GFP_KERNEL);
1469 if (sbi->s_flex_groups == NULL) {
1470 printk(KERN_ERR "EXT4-fs: not enough memory\n");
1471 goto failed;
1472 }
1473 memset(sbi->s_flex_groups, 0, flex_group_count *
1474 sizeof(struct flex_groups));
1475
1476 gdp = ext4_get_group_desc(sb, 1, &bh);
1477 block_bitmap = ext4_block_bitmap(sb, gdp) - 1;
1478
1479 for (i = 0; i < sbi->s_groups_count; i++) {
1480 gdp = ext4_get_group_desc(sb, i, &bh);
1481
1482 flex_group = ext4_flex_group(sbi, i);
1483 sbi->s_flex_groups[flex_group].free_inodes +=
1484 le16_to_cpu(gdp->bg_free_inodes_count);
1485 sbi->s_flex_groups[flex_group].free_blocks +=
1486 le16_to_cpu(gdp->bg_free_blocks_count);
1487 }
1488
1489 return 1;
1490failed:
1491 return 0;
1492}
1493
1445__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, 1494__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
1446 struct ext4_group_desc *gdp) 1495 struct ext4_group_desc *gdp)
1447{ 1496{
@@ -2137,6 +2186,14 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
2137 printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n"); 2186 printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n");
2138 goto failed_mount2; 2187 goto failed_mount2;
2139 } 2188 }
2189 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
2190 if (!ext4_fill_flex_info(sb)) {
2191 printk(KERN_ERR
2192 "EXT4-fs: unable to initialize "
2193 "flex_bg meta info!\n");
2194 goto failed_mount2;
2195 }
2196
2140 sbi->s_gdb_count = db_count; 2197 sbi->s_gdb_count = db_count;
2141 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 2198 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
2142 spin_lock_init(&sbi->s_next_gen_lock); 2199 spin_lock_init(&sbi->s_next_gen_lock);