diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 57 |
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 | ||
1446 | static 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; | ||
1490 | failed: | ||
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); |