diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 111 |
1 files changed, 65 insertions, 46 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 40131b777af6..e32195d6aac3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -828,12 +828,22 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
828 | ei->cur_aio_dio = NULL; | 828 | ei->cur_aio_dio = NULL; |
829 | ei->i_sync_tid = 0; | 829 | ei->i_sync_tid = 0; |
830 | ei->i_datasync_tid = 0; | 830 | ei->i_datasync_tid = 0; |
831 | atomic_set(&ei->i_ioend_count, 0); | ||
831 | 832 | ||
832 | return &ei->vfs_inode; | 833 | return &ei->vfs_inode; |
833 | } | 834 | } |
834 | 835 | ||
836 | static int ext4_drop_inode(struct inode *inode) | ||
837 | { | ||
838 | int drop = generic_drop_inode(inode); | ||
839 | |||
840 | trace_ext4_drop_inode(inode, drop); | ||
841 | return drop; | ||
842 | } | ||
843 | |||
835 | static void ext4_destroy_inode(struct inode *inode) | 844 | static void ext4_destroy_inode(struct inode *inode) |
836 | { | 845 | { |
846 | ext4_ioend_wait(inode); | ||
837 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | 847 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
838 | ext4_msg(inode->i_sb, KERN_ERR, | 848 | ext4_msg(inode->i_sb, KERN_ERR, |
839 | "Inode %lu (%p): orphan list check failed!", | 849 | "Inode %lu (%p): orphan list check failed!", |
@@ -1173,6 +1183,7 @@ static const struct super_operations ext4_sops = { | |||
1173 | .destroy_inode = ext4_destroy_inode, | 1183 | .destroy_inode = ext4_destroy_inode, |
1174 | .write_inode = ext4_write_inode, | 1184 | .write_inode = ext4_write_inode, |
1175 | .dirty_inode = ext4_dirty_inode, | 1185 | .dirty_inode = ext4_dirty_inode, |
1186 | .drop_inode = ext4_drop_inode, | ||
1176 | .evict_inode = ext4_evict_inode, | 1187 | .evict_inode = ext4_evict_inode, |
1177 | .put_super = ext4_put_super, | 1188 | .put_super = ext4_put_super, |
1178 | .sync_fs = ext4_sync_fs, | 1189 | .sync_fs = ext4_sync_fs, |
@@ -1186,7 +1197,6 @@ static const struct super_operations ext4_sops = { | |||
1186 | .quota_write = ext4_quota_write, | 1197 | .quota_write = ext4_quota_write, |
1187 | #endif | 1198 | #endif |
1188 | .bdev_try_to_free_page = bdev_try_to_free_page, | 1199 | .bdev_try_to_free_page = bdev_try_to_free_page, |
1189 | .trim_fs = ext4_trim_fs | ||
1190 | }; | 1200 | }; |
1191 | 1201 | ||
1192 | static const struct super_operations ext4_nojournal_sops = { | 1202 | static const struct super_operations ext4_nojournal_sops = { |
@@ -1194,6 +1204,7 @@ static const struct super_operations ext4_nojournal_sops = { | |||
1194 | .destroy_inode = ext4_destroy_inode, | 1204 | .destroy_inode = ext4_destroy_inode, |
1195 | .write_inode = ext4_write_inode, | 1205 | .write_inode = ext4_write_inode, |
1196 | .dirty_inode = ext4_dirty_inode, | 1206 | .dirty_inode = ext4_dirty_inode, |
1207 | .drop_inode = ext4_drop_inode, | ||
1197 | .evict_inode = ext4_evict_inode, | 1208 | .evict_inode = ext4_evict_inode, |
1198 | .write_super = ext4_write_super, | 1209 | .write_super = ext4_write_super, |
1199 | .put_super = ext4_put_super, | 1210 | .put_super = ext4_put_super, |
@@ -2699,7 +2710,6 @@ static int ext4_lazyinit_thread(void *arg) | |||
2699 | struct ext4_li_request *elr; | 2710 | struct ext4_li_request *elr; |
2700 | unsigned long next_wakeup; | 2711 | unsigned long next_wakeup; |
2701 | DEFINE_WAIT(wait); | 2712 | DEFINE_WAIT(wait); |
2702 | int ret; | ||
2703 | 2713 | ||
2704 | BUG_ON(NULL == eli); | 2714 | BUG_ON(NULL == eli); |
2705 | 2715 | ||
@@ -2723,13 +2733,12 @@ cont_thread: | |||
2723 | elr = list_entry(pos, struct ext4_li_request, | 2733 | elr = list_entry(pos, struct ext4_li_request, |
2724 | lr_request); | 2734 | lr_request); |
2725 | 2735 | ||
2726 | if (time_after_eq(jiffies, elr->lr_next_sched)) | 2736 | if (time_after_eq(jiffies, elr->lr_next_sched)) { |
2727 | ret = ext4_run_li_request(elr); | 2737 | if (ext4_run_li_request(elr) != 0) { |
2728 | 2738 | /* error, remove the lazy_init job */ | |
2729 | if (ret) { | 2739 | ext4_remove_li_request(elr); |
2730 | ret = 0; | 2740 | continue; |
2731 | ext4_remove_li_request(elr); | 2741 | } |
2732 | continue; | ||
2733 | } | 2742 | } |
2734 | 2743 | ||
2735 | if (time_before(elr->lr_next_sched, next_wakeup)) | 2744 | if (time_before(elr->lr_next_sched, next_wakeup)) |
@@ -2740,7 +2749,8 @@ cont_thread: | |||
2740 | if (freezing(current)) | 2749 | if (freezing(current)) |
2741 | refrigerator(); | 2750 | refrigerator(); |
2742 | 2751 | ||
2743 | if (time_after_eq(jiffies, next_wakeup)) { | 2752 | if ((time_after_eq(jiffies, next_wakeup)) || |
2753 | (MAX_JIFFY_OFFSET == next_wakeup)) { | ||
2744 | cond_resched(); | 2754 | cond_resched(); |
2745 | continue; | 2755 | continue; |
2746 | } | 2756 | } |
@@ -2788,9 +2798,6 @@ static void ext4_clear_request_list(void) | |||
2788 | struct ext4_li_request *elr; | 2798 | struct ext4_li_request *elr; |
2789 | 2799 | ||
2790 | mutex_lock(&ext4_li_info->li_list_mtx); | 2800 | mutex_lock(&ext4_li_info->li_list_mtx); |
2791 | if (list_empty(&ext4_li_info->li_request_list)) | ||
2792 | return; | ||
2793 | |||
2794 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { | 2801 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { |
2795 | elr = list_entry(pos, struct ext4_li_request, | 2802 | elr = list_entry(pos, struct ext4_li_request, |
2796 | lr_request); | 2803 | lr_request); |
@@ -3257,13 +3264,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3257 | * Test whether we have more sectors than will fit in sector_t, | 3264 | * Test whether we have more sectors than will fit in sector_t, |
3258 | * and whether the max offset is addressable by the page cache. | 3265 | * and whether the max offset is addressable by the page cache. |
3259 | */ | 3266 | */ |
3260 | ret = generic_check_addressable(sb->s_blocksize_bits, | 3267 | err = generic_check_addressable(sb->s_blocksize_bits, |
3261 | ext4_blocks_count(es)); | 3268 | ext4_blocks_count(es)); |
3262 | if (ret) { | 3269 | if (err) { |
3263 | ext4_msg(sb, KERN_ERR, "filesystem" | 3270 | ext4_msg(sb, KERN_ERR, "filesystem" |
3264 | " too large to mount safely on this system"); | 3271 | " too large to mount safely on this system"); |
3265 | if (sizeof(sector_t) < 8) | 3272 | if (sizeof(sector_t) < 8) |
3266 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); | 3273 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); |
3274 | ret = err; | ||
3267 | goto failed_mount; | 3275 | goto failed_mount; |
3268 | } | 3276 | } |
3269 | 3277 | ||
@@ -3348,6 +3356,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3348 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 3356 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
3349 | spin_lock_init(&sbi->s_next_gen_lock); | 3357 | spin_lock_init(&sbi->s_next_gen_lock); |
3350 | 3358 | ||
3359 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | ||
3360 | ext4_count_free_blocks(sb)); | ||
3361 | if (!err) { | ||
3362 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
3363 | ext4_count_free_inodes(sb)); | ||
3364 | } | ||
3365 | if (!err) { | ||
3366 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
3367 | ext4_count_dirs(sb)); | ||
3368 | } | ||
3369 | if (!err) { | ||
3370 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | ||
3371 | } | ||
3372 | if (err) { | ||
3373 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3374 | goto failed_mount3; | ||
3375 | } | ||
3376 | |||
3351 | sbi->s_stripe = ext4_get_stripe_size(sbi); | 3377 | sbi->s_stripe = ext4_get_stripe_size(sbi); |
3352 | sbi->s_max_writeback_mb_bump = 128; | 3378 | sbi->s_max_writeback_mb_bump = 128; |
3353 | 3379 | ||
@@ -3446,22 +3472,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3446 | } | 3472 | } |
3447 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 3473 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
3448 | 3474 | ||
3449 | no_journal: | 3475 | /* |
3450 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | 3476 | * The journal may have updated the bg summary counts, so we |
3451 | ext4_count_free_blocks(sb)); | 3477 | * need to update the global counters. |
3452 | if (!err) | 3478 | */ |
3453 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | 3479 | percpu_counter_set(&sbi->s_freeblocks_counter, |
3454 | ext4_count_free_inodes(sb)); | 3480 | ext4_count_free_blocks(sb)); |
3455 | if (!err) | 3481 | percpu_counter_set(&sbi->s_freeinodes_counter, |
3456 | err = percpu_counter_init(&sbi->s_dirs_counter, | 3482 | ext4_count_free_inodes(sb)); |
3457 | ext4_count_dirs(sb)); | 3483 | percpu_counter_set(&sbi->s_dirs_counter, |
3458 | if (!err) | 3484 | ext4_count_dirs(sb)); |
3459 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | 3485 | percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); |
3460 | if (err) { | ||
3461 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3462 | goto failed_mount_wq; | ||
3463 | } | ||
3464 | 3486 | ||
3487 | no_journal: | ||
3465 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 3488 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
3466 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 3489 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
3467 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); | 3490 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); |
@@ -3611,10 +3634,6 @@ failed_mount_wq: | |||
3611 | jbd2_journal_destroy(sbi->s_journal); | 3634 | jbd2_journal_destroy(sbi->s_journal); |
3612 | sbi->s_journal = NULL; | 3635 | sbi->s_journal = NULL; |
3613 | } | 3636 | } |
3614 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3615 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3616 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3617 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3618 | failed_mount3: | 3637 | failed_mount3: |
3619 | if (sbi->s_flex_groups) { | 3638 | if (sbi->s_flex_groups) { |
3620 | if (is_vmalloc_addr(sbi->s_flex_groups)) | 3639 | if (is_vmalloc_addr(sbi->s_flex_groups)) |
@@ -3622,6 +3641,10 @@ failed_mount3: | |||
3622 | else | 3641 | else |
3623 | kfree(sbi->s_flex_groups); | 3642 | kfree(sbi->s_flex_groups); |
3624 | } | 3643 | } |
3644 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3645 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3646 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3647 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3625 | failed_mount2: | 3648 | failed_mount2: |
3626 | for (i = 0; i < db_count; i++) | 3649 | for (i = 0; i < db_count; i++) |
3627 | brelse(sbi->s_group_desc[i]); | 3650 | brelse(sbi->s_group_desc[i]); |
@@ -3949,13 +3972,11 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
3949 | else | 3972 | else |
3950 | es->s_kbytes_written = | 3973 | es->s_kbytes_written = |
3951 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); | 3974 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); |
3952 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter)) | 3975 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( |
3953 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( | 3976 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3954 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3977 | es->s_free_inodes_count = |
3955 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) | 3978 | cpu_to_le32(percpu_counter_sum_positive( |
3956 | es->s_free_inodes_count = | 3979 | &EXT4_SB(sb)->s_freeinodes_counter)); |
3957 | cpu_to_le32(percpu_counter_sum_positive( | ||
3958 | &EXT4_SB(sb)->s_freeinodes_counter)); | ||
3959 | sb->s_dirt = 0; | 3980 | sb->s_dirt = 0; |
3960 | BUFFER_TRACE(sbh, "marking dirty"); | 3981 | BUFFER_TRACE(sbh, "marking dirty"); |
3961 | mark_buffer_dirty(sbh); | 3982 | mark_buffer_dirty(sbh); |
@@ -4556,12 +4577,10 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
4556 | 4577 | ||
4557 | static int ext4_quota_off(struct super_block *sb, int type) | 4578 | static int ext4_quota_off(struct super_block *sb, int type) |
4558 | { | 4579 | { |
4559 | /* Force all delayed allocation blocks to be allocated */ | 4580 | /* Force all delayed allocation blocks to be allocated. |
4560 | if (test_opt(sb, DELALLOC)) { | 4581 | * Caller already holds s_umount sem */ |
4561 | down_read(&sb->s_umount); | 4582 | if (test_opt(sb, DELALLOC)) |
4562 | sync_filesystem(sb); | 4583 | sync_filesystem(sb); |
4563 | up_read(&sb->s_umount); | ||
4564 | } | ||
4565 | 4584 | ||
4566 | return dquot_quota_off(sb, type); | 4585 | return dquot_quota_off(sb, type); |
4567 | } | 4586 | } |