diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 189 |
1 files changed, 140 insertions, 49 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 94cc84db7c9a..b59373b625e9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -69,6 +69,7 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
69 | static void ext4_clear_journal_err(struct super_block *sb, | 69 | static void ext4_clear_journal_err(struct super_block *sb, |
70 | struct ext4_super_block *es); | 70 | struct ext4_super_block *es); |
71 | static int ext4_sync_fs(struct super_block *sb, int wait); | 71 | static int ext4_sync_fs(struct super_block *sb, int wait); |
72 | static int ext4_sync_fs_nojournal(struct super_block *sb, int wait); | ||
72 | static int ext4_remount(struct super_block *sb, int *flags, char *data); | 73 | static int ext4_remount(struct super_block *sb, int *flags, char *data); |
73 | static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); | 74 | static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); |
74 | static int ext4_unfreeze(struct super_block *sb); | 75 | static int ext4_unfreeze(struct super_block *sb); |
@@ -398,6 +399,11 @@ static void ext4_handle_error(struct super_block *sb) | |||
398 | } | 399 | } |
399 | if (test_opt(sb, ERRORS_RO)) { | 400 | if (test_opt(sb, ERRORS_RO)) { |
400 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); | 401 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); |
402 | /* | ||
403 | * Make sure updated value of ->s_mount_flags will be visible | ||
404 | * before ->s_flags update | ||
405 | */ | ||
406 | smp_wmb(); | ||
401 | sb->s_flags |= MS_RDONLY; | 407 | sb->s_flags |= MS_RDONLY; |
402 | } | 408 | } |
403 | if (test_opt(sb, ERRORS_PANIC)) | 409 | if (test_opt(sb, ERRORS_PANIC)) |
@@ -422,9 +428,9 @@ void __ext4_error(struct super_block *sb, const char *function, | |||
422 | ext4_handle_error(sb); | 428 | ext4_handle_error(sb); |
423 | } | 429 | } |
424 | 430 | ||
425 | void ext4_error_inode(struct inode *inode, const char *function, | 431 | void __ext4_error_inode(struct inode *inode, const char *function, |
426 | unsigned int line, ext4_fsblk_t block, | 432 | unsigned int line, ext4_fsblk_t block, |
427 | const char *fmt, ...) | 433 | const char *fmt, ...) |
428 | { | 434 | { |
429 | va_list args; | 435 | va_list args; |
430 | struct va_format vaf; | 436 | struct va_format vaf; |
@@ -451,9 +457,9 @@ void ext4_error_inode(struct inode *inode, const char *function, | |||
451 | ext4_handle_error(inode->i_sb); | 457 | ext4_handle_error(inode->i_sb); |
452 | } | 458 | } |
453 | 459 | ||
454 | void ext4_error_file(struct file *file, const char *function, | 460 | void __ext4_error_file(struct file *file, const char *function, |
455 | unsigned int line, ext4_fsblk_t block, | 461 | unsigned int line, ext4_fsblk_t block, |
456 | const char *fmt, ...) | 462 | const char *fmt, ...) |
457 | { | 463 | { |
458 | va_list args; | 464 | va_list args; |
459 | struct va_format vaf; | 465 | struct va_format vaf; |
@@ -570,8 +576,13 @@ void __ext4_abort(struct super_block *sb, const char *function, | |||
570 | 576 | ||
571 | if ((sb->s_flags & MS_RDONLY) == 0) { | 577 | if ((sb->s_flags & MS_RDONLY) == 0) { |
572 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); | 578 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); |
573 | sb->s_flags |= MS_RDONLY; | ||
574 | EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; | 579 | EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; |
580 | /* | ||
581 | * Make sure updated value of ->s_mount_flags will be visible | ||
582 | * before ->s_flags update | ||
583 | */ | ||
584 | smp_wmb(); | ||
585 | sb->s_flags |= MS_RDONLY; | ||
575 | if (EXT4_SB(sb)->s_journal) | 586 | if (EXT4_SB(sb)->s_journal) |
576 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); | 587 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); |
577 | save_error_info(sb, function, line); | 588 | save_error_info(sb, function, line); |
@@ -580,7 +591,8 @@ void __ext4_abort(struct super_block *sb, const char *function, | |||
580 | panic("EXT4-fs panic from previous error\n"); | 591 | panic("EXT4-fs panic from previous error\n"); |
581 | } | 592 | } |
582 | 593 | ||
583 | void ext4_msg(struct super_block *sb, const char *prefix, const char *fmt, ...) | 594 | void __ext4_msg(struct super_block *sb, |
595 | const char *prefix, const char *fmt, ...) | ||
584 | { | 596 | { |
585 | struct va_format vaf; | 597 | struct va_format vaf; |
586 | va_list args; | 598 | va_list args; |
@@ -750,8 +762,10 @@ static void ext4_put_super(struct super_block *sb) | |||
750 | ext4_unregister_li_request(sb); | 762 | ext4_unregister_li_request(sb); |
751 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | 763 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); |
752 | 764 | ||
753 | flush_workqueue(sbi->dio_unwritten_wq); | 765 | flush_workqueue(sbi->unrsv_conversion_wq); |
754 | destroy_workqueue(sbi->dio_unwritten_wq); | 766 | flush_workqueue(sbi->rsv_conversion_wq); |
767 | destroy_workqueue(sbi->unrsv_conversion_wq); | ||
768 | destroy_workqueue(sbi->rsv_conversion_wq); | ||
755 | 769 | ||
756 | if (sbi->s_journal) { | 770 | if (sbi->s_journal) { |
757 | err = jbd2_journal_destroy(sbi->s_journal); | 771 | err = jbd2_journal_destroy(sbi->s_journal); |
@@ -760,7 +774,7 @@ static void ext4_put_super(struct super_block *sb) | |||
760 | ext4_abort(sb, "Couldn't clean up the journal"); | 774 | ext4_abort(sb, "Couldn't clean up the journal"); |
761 | } | 775 | } |
762 | 776 | ||
763 | ext4_es_unregister_shrinker(sb); | 777 | ext4_es_unregister_shrinker(sbi); |
764 | del_timer(&sbi->s_err_report); | 778 | del_timer(&sbi->s_err_report); |
765 | ext4_release_system_zone(sb); | 779 | ext4_release_system_zone(sb); |
766 | ext4_mb_release(sb); | 780 | ext4_mb_release(sb); |
@@ -849,6 +863,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
849 | rwlock_init(&ei->i_es_lock); | 863 | rwlock_init(&ei->i_es_lock); |
850 | INIT_LIST_HEAD(&ei->i_es_lru); | 864 | INIT_LIST_HEAD(&ei->i_es_lru); |
851 | ei->i_es_lru_nr = 0; | 865 | ei->i_es_lru_nr = 0; |
866 | ei->i_touch_when = 0; | ||
852 | ei->i_reserved_data_blocks = 0; | 867 | ei->i_reserved_data_blocks = 0; |
853 | ei->i_reserved_meta_blocks = 0; | 868 | ei->i_reserved_meta_blocks = 0; |
854 | ei->i_allocated_meta_blocks = 0; | 869 | ei->i_allocated_meta_blocks = 0; |
@@ -859,13 +874,15 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
859 | ei->i_reserved_quota = 0; | 874 | ei->i_reserved_quota = 0; |
860 | #endif | 875 | #endif |
861 | ei->jinode = NULL; | 876 | ei->jinode = NULL; |
862 | INIT_LIST_HEAD(&ei->i_completed_io_list); | 877 | INIT_LIST_HEAD(&ei->i_rsv_conversion_list); |
878 | INIT_LIST_HEAD(&ei->i_unrsv_conversion_list); | ||
863 | spin_lock_init(&ei->i_completed_io_lock); | 879 | spin_lock_init(&ei->i_completed_io_lock); |
864 | ei->i_sync_tid = 0; | 880 | ei->i_sync_tid = 0; |
865 | ei->i_datasync_tid = 0; | 881 | ei->i_datasync_tid = 0; |
866 | atomic_set(&ei->i_ioend_count, 0); | 882 | atomic_set(&ei->i_ioend_count, 0); |
867 | atomic_set(&ei->i_unwritten, 0); | 883 | atomic_set(&ei->i_unwritten, 0); |
868 | INIT_WORK(&ei->i_unwritten_work, ext4_end_io_work); | 884 | INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work); |
885 | INIT_WORK(&ei->i_unrsv_conversion_work, ext4_end_io_unrsv_work); | ||
869 | 886 | ||
870 | return &ei->vfs_inode; | 887 | return &ei->vfs_inode; |
871 | } | 888 | } |
@@ -1093,6 +1110,7 @@ static const struct super_operations ext4_nojournal_sops = { | |||
1093 | .dirty_inode = ext4_dirty_inode, | 1110 | .dirty_inode = ext4_dirty_inode, |
1094 | .drop_inode = ext4_drop_inode, | 1111 | .drop_inode = ext4_drop_inode, |
1095 | .evict_inode = ext4_evict_inode, | 1112 | .evict_inode = ext4_evict_inode, |
1113 | .sync_fs = ext4_sync_fs_nojournal, | ||
1096 | .put_super = ext4_put_super, | 1114 | .put_super = ext4_put_super, |
1097 | .statfs = ext4_statfs, | 1115 | .statfs = ext4_statfs, |
1098 | .remount_fs = ext4_remount, | 1116 | .remount_fs = ext4_remount, |
@@ -1341,7 +1359,7 @@ static const struct mount_opts { | |||
1341 | {Opt_delalloc, EXT4_MOUNT_DELALLOC, | 1359 | {Opt_delalloc, EXT4_MOUNT_DELALLOC, |
1342 | MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, | 1360 | MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, |
1343 | {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, | 1361 | {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, |
1344 | MOPT_EXT4_ONLY | MOPT_CLEAR | MOPT_EXPLICIT}, | 1362 | MOPT_EXT4_ONLY | MOPT_CLEAR}, |
1345 | {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, | 1363 | {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, |
1346 | MOPT_EXT4_ONLY | MOPT_SET}, | 1364 | MOPT_EXT4_ONLY | MOPT_SET}, |
1347 | {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT | | 1365 | {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT | |
@@ -1684,12 +1702,6 @@ static inline void ext4_show_quota_options(struct seq_file *seq, | |||
1684 | 1702 | ||
1685 | if (sbi->s_qf_names[GRPQUOTA]) | 1703 | if (sbi->s_qf_names[GRPQUOTA]) |
1686 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | 1704 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); |
1687 | |||
1688 | if (test_opt(sb, USRQUOTA)) | ||
1689 | seq_puts(seq, ",usrquota"); | ||
1690 | |||
1691 | if (test_opt(sb, GRPQUOTA)) | ||
1692 | seq_puts(seq, ",grpquota"); | ||
1693 | #endif | 1705 | #endif |
1694 | } | 1706 | } |
1695 | 1707 | ||
@@ -1908,7 +1920,6 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1908 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1920 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1909 | struct ext4_group_desc *gdp = NULL; | 1921 | struct ext4_group_desc *gdp = NULL; |
1910 | ext4_group_t flex_group; | 1922 | ext4_group_t flex_group; |
1911 | unsigned int groups_per_flex = 0; | ||
1912 | int i, err; | 1923 | int i, err; |
1913 | 1924 | ||
1914 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; | 1925 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; |
@@ -1916,7 +1927,6 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1916 | sbi->s_log_groups_per_flex = 0; | 1927 | sbi->s_log_groups_per_flex = 0; |
1917 | return 1; | 1928 | return 1; |
1918 | } | 1929 | } |
1919 | groups_per_flex = 1U << sbi->s_log_groups_per_flex; | ||
1920 | 1930 | ||
1921 | err = ext4_alloc_flex_bg_array(sb, sbi->s_groups_count); | 1931 | err = ext4_alloc_flex_bg_array(sb, sbi->s_groups_count); |
1922 | if (err) | 1932 | if (err) |
@@ -2164,19 +2174,22 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
2164 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); | 2174 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); |
2165 | dquot_initialize(inode); | 2175 | dquot_initialize(inode); |
2166 | if (inode->i_nlink) { | 2176 | if (inode->i_nlink) { |
2167 | ext4_msg(sb, KERN_DEBUG, | 2177 | if (test_opt(sb, DEBUG)) |
2168 | "%s: truncating inode %lu to %lld bytes", | 2178 | ext4_msg(sb, KERN_DEBUG, |
2169 | __func__, inode->i_ino, inode->i_size); | 2179 | "%s: truncating inode %lu to %lld bytes", |
2180 | __func__, inode->i_ino, inode->i_size); | ||
2170 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", | 2181 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", |
2171 | inode->i_ino, inode->i_size); | 2182 | inode->i_ino, inode->i_size); |
2172 | mutex_lock(&inode->i_mutex); | 2183 | mutex_lock(&inode->i_mutex); |
2184 | truncate_inode_pages(inode->i_mapping, inode->i_size); | ||
2173 | ext4_truncate(inode); | 2185 | ext4_truncate(inode); |
2174 | mutex_unlock(&inode->i_mutex); | 2186 | mutex_unlock(&inode->i_mutex); |
2175 | nr_truncates++; | 2187 | nr_truncates++; |
2176 | } else { | 2188 | } else { |
2177 | ext4_msg(sb, KERN_DEBUG, | 2189 | if (test_opt(sb, DEBUG)) |
2178 | "%s: deleting unreferenced inode %lu", | 2190 | ext4_msg(sb, KERN_DEBUG, |
2179 | __func__, inode->i_ino); | 2191 | "%s: deleting unreferenced inode %lu", |
2192 | __func__, inode->i_ino); | ||
2180 | jbd_debug(2, "deleting unreferenced inode %lu\n", | 2193 | jbd_debug(2, "deleting unreferenced inode %lu\n", |
2181 | inode->i_ino); | 2194 | inode->i_ino); |
2182 | nr_orphans++; | 2195 | nr_orphans++; |
@@ -2377,7 +2390,10 @@ struct ext4_attr { | |||
2377 | ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *); | 2390 | ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *); |
2378 | ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *, | 2391 | ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *, |
2379 | const char *, size_t); | 2392 | const char *, size_t); |
2380 | int offset; | 2393 | union { |
2394 | int offset; | ||
2395 | int deprecated_val; | ||
2396 | } u; | ||
2381 | }; | 2397 | }; |
2382 | 2398 | ||
2383 | static int parse_strtoull(const char *buf, | 2399 | static int parse_strtoull(const char *buf, |
@@ -2446,7 +2462,7 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a, | |||
2446 | static ssize_t sbi_ui_show(struct ext4_attr *a, | 2462 | static ssize_t sbi_ui_show(struct ext4_attr *a, |
2447 | struct ext4_sb_info *sbi, char *buf) | 2463 | struct ext4_sb_info *sbi, char *buf) |
2448 | { | 2464 | { |
2449 | unsigned int *ui = (unsigned int *) (((char *) sbi) + a->offset); | 2465 | unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset); |
2450 | 2466 | ||
2451 | return snprintf(buf, PAGE_SIZE, "%u\n", *ui); | 2467 | return snprintf(buf, PAGE_SIZE, "%u\n", *ui); |
2452 | } | 2468 | } |
@@ -2455,7 +2471,7 @@ static ssize_t sbi_ui_store(struct ext4_attr *a, | |||
2455 | struct ext4_sb_info *sbi, | 2471 | struct ext4_sb_info *sbi, |
2456 | const char *buf, size_t count) | 2472 | const char *buf, size_t count) |
2457 | { | 2473 | { |
2458 | unsigned int *ui = (unsigned int *) (((char *) sbi) + a->offset); | 2474 | unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset); |
2459 | unsigned long t; | 2475 | unsigned long t; |
2460 | int ret; | 2476 | int ret; |
2461 | 2477 | ||
@@ -2504,12 +2520,20 @@ static ssize_t trigger_test_error(struct ext4_attr *a, | |||
2504 | return count; | 2520 | return count; |
2505 | } | 2521 | } |
2506 | 2522 | ||
2523 | static ssize_t sbi_deprecated_show(struct ext4_attr *a, | ||
2524 | struct ext4_sb_info *sbi, char *buf) | ||
2525 | { | ||
2526 | return snprintf(buf, PAGE_SIZE, "%d\n", a->u.deprecated_val); | ||
2527 | } | ||
2528 | |||
2507 | #define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \ | 2529 | #define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \ |
2508 | static struct ext4_attr ext4_attr_##_name = { \ | 2530 | static struct ext4_attr ext4_attr_##_name = { \ |
2509 | .attr = {.name = __stringify(_name), .mode = _mode }, \ | 2531 | .attr = {.name = __stringify(_name), .mode = _mode }, \ |
2510 | .show = _show, \ | 2532 | .show = _show, \ |
2511 | .store = _store, \ | 2533 | .store = _store, \ |
2512 | .offset = offsetof(struct ext4_sb_info, _elname), \ | 2534 | .u = { \ |
2535 | .offset = offsetof(struct ext4_sb_info, _elname),\ | ||
2536 | }, \ | ||
2513 | } | 2537 | } |
2514 | #define EXT4_ATTR(name, mode, show, store) \ | 2538 | #define EXT4_ATTR(name, mode, show, store) \ |
2515 | static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) | 2539 | static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) |
@@ -2520,6 +2544,14 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) | |||
2520 | #define EXT4_RW_ATTR_SBI_UI(name, elname) \ | 2544 | #define EXT4_RW_ATTR_SBI_UI(name, elname) \ |
2521 | EXT4_ATTR_OFFSET(name, 0644, sbi_ui_show, sbi_ui_store, elname) | 2545 | EXT4_ATTR_OFFSET(name, 0644, sbi_ui_show, sbi_ui_store, elname) |
2522 | #define ATTR_LIST(name) &ext4_attr_##name.attr | 2546 | #define ATTR_LIST(name) &ext4_attr_##name.attr |
2547 | #define EXT4_DEPRECATED_ATTR(_name, _val) \ | ||
2548 | static struct ext4_attr ext4_attr_##_name = { \ | ||
2549 | .attr = {.name = __stringify(_name), .mode = 0444 }, \ | ||
2550 | .show = sbi_deprecated_show, \ | ||
2551 | .u = { \ | ||
2552 | .deprecated_val = _val, \ | ||
2553 | }, \ | ||
2554 | } | ||
2523 | 2555 | ||
2524 | EXT4_RO_ATTR(delayed_allocation_blocks); | 2556 | EXT4_RO_ATTR(delayed_allocation_blocks); |
2525 | EXT4_RO_ATTR(session_write_kbytes); | 2557 | EXT4_RO_ATTR(session_write_kbytes); |
@@ -2534,7 +2566,7 @@ EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); | |||
2534 | EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); | 2566 | EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); |
2535 | EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); | 2567 | EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); |
2536 | EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); | 2568 | EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); |
2537 | EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump); | 2569 | EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128); |
2538 | EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); | 2570 | EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); |
2539 | EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error); | 2571 | EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error); |
2540 | 2572 | ||
@@ -3451,7 +3483,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3451 | } | 3483 | } |
3452 | if (test_opt(sb, DIOREAD_NOLOCK)) { | 3484 | if (test_opt(sb, DIOREAD_NOLOCK)) { |
3453 | ext4_msg(sb, KERN_ERR, "can't mount with " | 3485 | ext4_msg(sb, KERN_ERR, "can't mount with " |
3454 | "both data=journal and delalloc"); | 3486 | "both data=journal and dioread_nolock"); |
3455 | goto failed_mount; | 3487 | goto failed_mount; |
3456 | } | 3488 | } |
3457 | if (test_opt(sb, DELALLOC)) | 3489 | if (test_opt(sb, DELALLOC)) |
@@ -3586,10 +3618,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3586 | sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb)); | 3618 | sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb)); |
3587 | sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb)); | 3619 | sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb)); |
3588 | 3620 | ||
3589 | /* Do we have standard group size of blocksize * 8 blocks ? */ | ||
3590 | if (sbi->s_blocks_per_group == blocksize << 3) | ||
3591 | set_opt2(sb, STD_GROUP_SIZE); | ||
3592 | |||
3593 | for (i = 0; i < 4; i++) | 3621 | for (i = 0; i < 4; i++) |
3594 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); | 3622 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); |
3595 | sbi->s_def_hash_version = es->s_def_hash_version; | 3623 | sbi->s_def_hash_version = es->s_def_hash_version; |
@@ -3659,6 +3687,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3659 | goto failed_mount; | 3687 | goto failed_mount; |
3660 | } | 3688 | } |
3661 | 3689 | ||
3690 | /* Do we have standard group size of clustersize * 8 blocks ? */ | ||
3691 | if (sbi->s_blocks_per_group == clustersize << 3) | ||
3692 | set_opt2(sb, STD_GROUP_SIZE); | ||
3693 | |||
3662 | /* | 3694 | /* |
3663 | * Test whether we have more sectors than will fit in sector_t, | 3695 | * Test whether we have more sectors than will fit in sector_t, |
3664 | * and whether the max offset is addressable by the page cache. | 3696 | * and whether the max offset is addressable by the page cache. |
@@ -3763,7 +3795,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3763 | sbi->s_err_report.data = (unsigned long) sb; | 3795 | sbi->s_err_report.data = (unsigned long) sb; |
3764 | 3796 | ||
3765 | /* Register extent status tree shrinker */ | 3797 | /* Register extent status tree shrinker */ |
3766 | ext4_es_register_shrinker(sb); | 3798 | ext4_es_register_shrinker(sbi); |
3767 | 3799 | ||
3768 | err = percpu_counter_init(&sbi->s_freeclusters_counter, | 3800 | err = percpu_counter_init(&sbi->s_freeclusters_counter, |
3769 | ext4_count_free_clusters(sb)); | 3801 | ext4_count_free_clusters(sb)); |
@@ -3787,7 +3819,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3787 | } | 3819 | } |
3788 | 3820 | ||
3789 | sbi->s_stripe = ext4_get_stripe_size(sbi); | 3821 | sbi->s_stripe = ext4_get_stripe_size(sbi); |
3790 | sbi->s_max_writeback_mb_bump = 128; | ||
3791 | sbi->s_extent_max_zeroout_kb = 32; | 3822 | sbi->s_extent_max_zeroout_kb = 32; |
3792 | 3823 | ||
3793 | /* | 3824 | /* |
@@ -3915,12 +3946,20 @@ no_journal: | |||
3915 | * The maximum number of concurrent works can be high and | 3946 | * The maximum number of concurrent works can be high and |
3916 | * concurrency isn't really necessary. Limit it to 1. | 3947 | * concurrency isn't really necessary. Limit it to 1. |
3917 | */ | 3948 | */ |
3918 | EXT4_SB(sb)->dio_unwritten_wq = | 3949 | EXT4_SB(sb)->rsv_conversion_wq = |
3919 | alloc_workqueue("ext4-dio-unwritten", WQ_MEM_RECLAIM | WQ_UNBOUND, 1); | 3950 | alloc_workqueue("ext4-rsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1); |
3920 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 3951 | if (!EXT4_SB(sb)->rsv_conversion_wq) { |
3921 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); | 3952 | printk(KERN_ERR "EXT4-fs: failed to create workqueue\n"); |
3922 | ret = -ENOMEM; | 3953 | ret = -ENOMEM; |
3923 | goto failed_mount_wq; | 3954 | goto failed_mount4; |
3955 | } | ||
3956 | |||
3957 | EXT4_SB(sb)->unrsv_conversion_wq = | ||
3958 | alloc_workqueue("ext4-unrsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1); | ||
3959 | if (!EXT4_SB(sb)->unrsv_conversion_wq) { | ||
3960 | printk(KERN_ERR "EXT4-fs: failed to create workqueue\n"); | ||
3961 | ret = -ENOMEM; | ||
3962 | goto failed_mount4; | ||
3924 | } | 3963 | } |
3925 | 3964 | ||
3926 | /* | 3965 | /* |
@@ -4074,14 +4113,17 @@ failed_mount4a: | |||
4074 | sb->s_root = NULL; | 4113 | sb->s_root = NULL; |
4075 | failed_mount4: | 4114 | failed_mount4: |
4076 | ext4_msg(sb, KERN_ERR, "mount failed"); | 4115 | ext4_msg(sb, KERN_ERR, "mount failed"); |
4077 | destroy_workqueue(EXT4_SB(sb)->dio_unwritten_wq); | 4116 | if (EXT4_SB(sb)->rsv_conversion_wq) |
4117 | destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq); | ||
4118 | if (EXT4_SB(sb)->unrsv_conversion_wq) | ||
4119 | destroy_workqueue(EXT4_SB(sb)->unrsv_conversion_wq); | ||
4078 | failed_mount_wq: | 4120 | failed_mount_wq: |
4079 | if (sbi->s_journal) { | 4121 | if (sbi->s_journal) { |
4080 | jbd2_journal_destroy(sbi->s_journal); | 4122 | jbd2_journal_destroy(sbi->s_journal); |
4081 | sbi->s_journal = NULL; | 4123 | sbi->s_journal = NULL; |
4082 | } | 4124 | } |
4083 | failed_mount3: | 4125 | failed_mount3: |
4084 | ext4_es_unregister_shrinker(sb); | 4126 | ext4_es_unregister_shrinker(sbi); |
4085 | del_timer(&sbi->s_err_report); | 4127 | del_timer(&sbi->s_err_report); |
4086 | if (sbi->s_flex_groups) | 4128 | if (sbi->s_flex_groups) |
4087 | ext4_kvfree(sbi->s_flex_groups); | 4129 | ext4_kvfree(sbi->s_flex_groups); |
@@ -4517,19 +4559,52 @@ static int ext4_sync_fs(struct super_block *sb, int wait) | |||
4517 | { | 4559 | { |
4518 | int ret = 0; | 4560 | int ret = 0; |
4519 | tid_t target; | 4561 | tid_t target; |
4562 | bool needs_barrier = false; | ||
4520 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 4563 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
4521 | 4564 | ||
4522 | trace_ext4_sync_fs(sb, wait); | 4565 | trace_ext4_sync_fs(sb, wait); |
4523 | flush_workqueue(sbi->dio_unwritten_wq); | 4566 | flush_workqueue(sbi->rsv_conversion_wq); |
4567 | flush_workqueue(sbi->unrsv_conversion_wq); | ||
4524 | /* | 4568 | /* |
4525 | * Writeback quota in non-journalled quota case - journalled quota has | 4569 | * Writeback quota in non-journalled quota case - journalled quota has |
4526 | * no dirty dquots | 4570 | * no dirty dquots |
4527 | */ | 4571 | */ |
4528 | dquot_writeback_dquots(sb, -1); | 4572 | dquot_writeback_dquots(sb, -1); |
4573 | /* | ||
4574 | * Data writeback is possible w/o journal transaction, so barrier must | ||
4575 | * being sent at the end of the function. But we can skip it if | ||
4576 | * transaction_commit will do it for us. | ||
4577 | */ | ||
4578 | target = jbd2_get_latest_transaction(sbi->s_journal); | ||
4579 | if (wait && sbi->s_journal->j_flags & JBD2_BARRIER && | ||
4580 | !jbd2_trans_will_send_data_barrier(sbi->s_journal, target)) | ||
4581 | needs_barrier = true; | ||
4582 | |||
4529 | if (jbd2_journal_start_commit(sbi->s_journal, &target)) { | 4583 | if (jbd2_journal_start_commit(sbi->s_journal, &target)) { |
4530 | if (wait) | 4584 | if (wait) |
4531 | jbd2_log_wait_commit(sbi->s_journal, target); | 4585 | ret = jbd2_log_wait_commit(sbi->s_journal, target); |
4532 | } | 4586 | } |
4587 | if (needs_barrier) { | ||
4588 | int err; | ||
4589 | err = blkdev_issue_flush(sb->s_bdev, GFP_KERNEL, NULL); | ||
4590 | if (!ret) | ||
4591 | ret = err; | ||
4592 | } | ||
4593 | |||
4594 | return ret; | ||
4595 | } | ||
4596 | |||
4597 | static int ext4_sync_fs_nojournal(struct super_block *sb, int wait) | ||
4598 | { | ||
4599 | int ret = 0; | ||
4600 | |||
4601 | trace_ext4_sync_fs(sb, wait); | ||
4602 | flush_workqueue(EXT4_SB(sb)->rsv_conversion_wq); | ||
4603 | flush_workqueue(EXT4_SB(sb)->unrsv_conversion_wq); | ||
4604 | dquot_writeback_dquots(sb, -1); | ||
4605 | if (wait && test_opt(sb, BARRIER)) | ||
4606 | ret = blkdev_issue_flush(sb->s_bdev, GFP_KERNEL, NULL); | ||
4607 | |||
4533 | return ret; | 4608 | return ret; |
4534 | } | 4609 | } |
4535 | 4610 | ||
@@ -4652,6 +4727,21 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4652 | goto restore_opts; | 4727 | goto restore_opts; |
4653 | } | 4728 | } |
4654 | 4729 | ||
4730 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
4731 | if (test_opt2(sb, EXPLICIT_DELALLOC)) { | ||
4732 | ext4_msg(sb, KERN_ERR, "can't mount with " | ||
4733 | "both data=journal and delalloc"); | ||
4734 | err = -EINVAL; | ||
4735 | goto restore_opts; | ||
4736 | } | ||
4737 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
4738 | ext4_msg(sb, KERN_ERR, "can't mount with " | ||
4739 | "both data=journal and dioread_nolock"); | ||
4740 | err = -EINVAL; | ||
4741 | goto restore_opts; | ||
4742 | } | ||
4743 | } | ||
4744 | |||
4655 | if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) | 4745 | if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) |
4656 | ext4_abort(sb, "Abort forced by user"); | 4746 | ext4_abort(sb, "Abort forced by user"); |
4657 | 4747 | ||
@@ -5406,6 +5496,7 @@ static void __exit ext4_exit_fs(void) | |||
5406 | kset_unregister(ext4_kset); | 5496 | kset_unregister(ext4_kset); |
5407 | ext4_exit_system_zone(); | 5497 | ext4_exit_system_zone(); |
5408 | ext4_exit_pageio(); | 5498 | ext4_exit_pageio(); |
5499 | ext4_exit_es(); | ||
5409 | } | 5500 | } |
5410 | 5501 | ||
5411 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); | 5502 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); |