aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2010-11-03 12:03:21 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-11-03 12:03:21 -0400
commitce7e010aef63dc6b37a2354f7c9f5f4aedb37978 (patch)
tree458ee0c4887e989522e62701350edf9571dfce48 /fs/ext4/super.c
parentb2c78cd09b6ef78c8f20190f0b3e6df1d3651b70 (diff)
ext4: initialize the percpu counters before replaying the journal
We now initialize the percpu counters before replaying the journal, but after the journal, we recalculate the global counters, to deal with the possibility of the per-blockgroup counts getting updated by the journal replay. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c65
1 files changed, 39 insertions, 26 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 4d7ef31eacb1..04352e9729d0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3347,6 +3347,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3347 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 3347 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
3348 spin_lock_init(&sbi->s_next_gen_lock); 3348 spin_lock_init(&sbi->s_next_gen_lock);
3349 3349
3350 err = percpu_counter_init(&sbi->s_freeblocks_counter,
3351 ext4_count_free_blocks(sb));
3352 if (!err) {
3353 err = percpu_counter_init(&sbi->s_freeinodes_counter,
3354 ext4_count_free_inodes(sb));
3355 }
3356 if (!err) {
3357 err = percpu_counter_init(&sbi->s_dirs_counter,
3358 ext4_count_dirs(sb));
3359 }
3360 if (!err) {
3361 err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0);
3362 }
3363 if (err) {
3364 ext4_msg(sb, KERN_ERR, "insufficient memory");
3365 goto failed_mount3;
3366 }
3367
3350 sbi->s_stripe = ext4_get_stripe_size(sbi); 3368 sbi->s_stripe = ext4_get_stripe_size(sbi);
3351 sbi->s_max_writeback_mb_bump = 128; 3369 sbi->s_max_writeback_mb_bump = 128;
3352 3370
@@ -3445,22 +3463,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3445 } 3463 }
3446 set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); 3464 set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
3447 3465
3448no_journal: 3466 /*
3449 err = percpu_counter_init(&sbi->s_freeblocks_counter, 3467 * The journal may have updated the bg summary counts, so we
3450 ext4_count_free_blocks(sb)); 3468 * need to update the global counters.
3451 if (!err) 3469 */
3452 err = percpu_counter_init(&sbi->s_freeinodes_counter, 3470 percpu_counter_set(&sbi->s_freeblocks_counter,
3453 ext4_count_free_inodes(sb)); 3471 ext4_count_free_blocks(sb));
3454 if (!err) 3472 percpu_counter_set(&sbi->s_freeinodes_counter,
3455 err = percpu_counter_init(&sbi->s_dirs_counter, 3473 ext4_count_free_inodes(sb));
3456 ext4_count_dirs(sb)); 3474 percpu_counter_set(&sbi->s_dirs_counter,
3457 if (!err) 3475 ext4_count_dirs(sb));
3458 err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); 3476 percpu_counter_set(&sbi->s_dirtyblocks_counter, 0);
3459 if (err) {
3460 ext4_msg(sb, KERN_ERR, "insufficient memory");
3461 goto failed_mount_wq;
3462 }
3463 3477
3478no_journal:
3464 EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); 3479 EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten");
3465 if (!EXT4_SB(sb)->dio_unwritten_wq) { 3480 if (!EXT4_SB(sb)->dio_unwritten_wq) {
3466 printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); 3481 printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n");
@@ -3610,10 +3625,6 @@ failed_mount_wq:
3610 jbd2_journal_destroy(sbi->s_journal); 3625 jbd2_journal_destroy(sbi->s_journal);
3611 sbi->s_journal = NULL; 3626 sbi->s_journal = NULL;
3612 } 3627 }
3613 percpu_counter_destroy(&sbi->s_freeblocks_counter);
3614 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3615 percpu_counter_destroy(&sbi->s_dirs_counter);
3616 percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
3617failed_mount3: 3628failed_mount3:
3618 if (sbi->s_flex_groups) { 3629 if (sbi->s_flex_groups) {
3619 if (is_vmalloc_addr(sbi->s_flex_groups)) 3630 if (is_vmalloc_addr(sbi->s_flex_groups))
@@ -3621,6 +3632,10 @@ failed_mount3:
3621 else 3632 else
3622 kfree(sbi->s_flex_groups); 3633 kfree(sbi->s_flex_groups);
3623 } 3634 }
3635 percpu_counter_destroy(&sbi->s_freeblocks_counter);
3636 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3637 percpu_counter_destroy(&sbi->s_dirs_counter);
3638 percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
3624failed_mount2: 3639failed_mount2:
3625 for (i = 0; i < db_count; i++) 3640 for (i = 0; i < db_count; i++)
3626 brelse(sbi->s_group_desc[i]); 3641 brelse(sbi->s_group_desc[i]);
@@ -3948,13 +3963,11 @@ static int ext4_commit_super(struct super_block *sb, int sync)
3948 else 3963 else
3949 es->s_kbytes_written = 3964 es->s_kbytes_written =
3950 cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); 3965 cpu_to_le64(EXT4_SB(sb)->s_kbytes_written);
3951 if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter)) 3966 ext4_free_blocks_count_set(es, percpu_counter_sum_positive(
3952 ext4_free_blocks_count_set(es, percpu_counter_sum_positive( 3967 &EXT4_SB(sb)->s_freeblocks_counter));
3953 &EXT4_SB(sb)->s_freeblocks_counter)); 3968 es->s_free_inodes_count =
3954 if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) 3969 cpu_to_le32(percpu_counter_sum_positive(
3955 es->s_free_inodes_count = 3970 &EXT4_SB(sb)->s_freeinodes_counter));
3956 cpu_to_le32(percpu_counter_sum_positive(
3957 &EXT4_SB(sb)->s_freeinodes_counter));
3958 sb->s_dirt = 0; 3971 sb->s_dirt = 0;
3959 BUFFER_TRACE(sbh, "marking dirty"); 3972 BUFFER_TRACE(sbh, "marking dirty");
3960 mark_buffer_dirty(sbh); 3973 mark_buffer_dirty(sbh);