aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
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);