提交 ce7e010a 编写于 作者: T Theodore Ts'o

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: N"Theodore Ts'o" <tytso@mit.edu>
上级 b2c78cd0
...@@ -3347,6 +3347,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3347,6 +3347,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
get_random_bytes(&sbi->s_next_generation, sizeof(u32)); get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock); spin_lock_init(&sbi->s_next_gen_lock);
err = percpu_counter_init(&sbi->s_freeblocks_counter,
ext4_count_free_blocks(sb));
if (!err) {
err = percpu_counter_init(&sbi->s_freeinodes_counter,
ext4_count_free_inodes(sb));
}
if (!err) {
err = percpu_counter_init(&sbi->s_dirs_counter,
ext4_count_dirs(sb));
}
if (!err) {
err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0);
}
if (err) {
ext4_msg(sb, KERN_ERR, "insufficient memory");
goto failed_mount3;
}
sbi->s_stripe = ext4_get_stripe_size(sbi); sbi->s_stripe = ext4_get_stripe_size(sbi);
sbi->s_max_writeback_mb_bump = 128; sbi->s_max_writeback_mb_bump = 128;
...@@ -3445,22 +3463,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3445,22 +3463,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
} }
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
no_journal: /*
err = percpu_counter_init(&sbi->s_freeblocks_counter, * The journal may have updated the bg summary counts, so we
ext4_count_free_blocks(sb)); * need to update the global counters.
if (!err) */
err = percpu_counter_init(&sbi->s_freeinodes_counter, percpu_counter_set(&sbi->s_freeblocks_counter,
ext4_count_free_inodes(sb)); ext4_count_free_blocks(sb));
if (!err) percpu_counter_set(&sbi->s_freeinodes_counter,
err = percpu_counter_init(&sbi->s_dirs_counter, ext4_count_free_inodes(sb));
ext4_count_dirs(sb)); percpu_counter_set(&sbi->s_dirs_counter,
if (!err) ext4_count_dirs(sb));
err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); percpu_counter_set(&sbi->s_dirtyblocks_counter, 0);
if (err) {
ext4_msg(sb, KERN_ERR, "insufficient memory");
goto failed_mount_wq;
}
no_journal:
EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten");
if (!EXT4_SB(sb)->dio_unwritten_wq) { if (!EXT4_SB(sb)->dio_unwritten_wq) {
printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n");
...@@ -3610,10 +3625,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3610,10 +3625,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
jbd2_journal_destroy(sbi->s_journal); jbd2_journal_destroy(sbi->s_journal);
sbi->s_journal = NULL; sbi->s_journal = NULL;
} }
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
failed_mount3: failed_mount3:
if (sbi->s_flex_groups) { if (sbi->s_flex_groups) {
if (is_vmalloc_addr(sbi->s_flex_groups)) if (is_vmalloc_addr(sbi->s_flex_groups))
...@@ -3621,6 +3632,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3621,6 +3632,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
else else
kfree(sbi->s_flex_groups); kfree(sbi->s_flex_groups);
} }
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
failed_mount2: failed_mount2:
for (i = 0; i < db_count; i++) for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]); brelse(sbi->s_group_desc[i]);
...@@ -3948,13 +3963,11 @@ static int ext4_commit_super(struct super_block *sb, int sync) ...@@ -3948,13 +3963,11 @@ static int ext4_commit_super(struct super_block *sb, int sync)
else else
es->s_kbytes_written = es->s_kbytes_written =
cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); cpu_to_le64(EXT4_SB(sb)->s_kbytes_written);
if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter)) ext4_free_blocks_count_set(es, percpu_counter_sum_positive(
ext4_free_blocks_count_set(es, percpu_counter_sum_positive( &EXT4_SB(sb)->s_freeblocks_counter));
&EXT4_SB(sb)->s_freeblocks_counter)); es->s_free_inodes_count =
if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) cpu_to_le32(percpu_counter_sum_positive(
es->s_free_inodes_count = &EXT4_SB(sb)->s_freeinodes_counter));
cpu_to_le32(percpu_counter_sum_positive(
&EXT4_SB(sb)->s_freeinodes_counter));
sb->s_dirt = 0; sb->s_dirt = 0;
BUFFER_TRACE(sbh, "marking dirty"); BUFFER_TRACE(sbh, "marking dirty");
mark_buffer_dirty(sbh); mark_buffer_dirty(sbh);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册