diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/super.c | 65 |
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 | ||
3448 | no_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 | ||
3478 | no_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); | ||
3617 | failed_mount3: | 3628 | failed_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); | ||
3624 | failed_mount2: | 3639 | failed_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); |