diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 630 |
1 files changed, 565 insertions, 65 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7f47c366bf15..61182fe6254e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
28 | #include <linux/parser.h> | 28 | #include <linux/parser.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/buffer_head.h> | 29 | #include <linux/buffer_head.h> |
31 | #include <linux/exportfs.h> | 30 | #include <linux/exportfs.h> |
32 | #include <linux/vfs.h> | 31 | #include <linux/vfs.h> |
@@ -41,6 +40,9 @@ | |||
41 | #include <linux/crc16.h> | 40 | #include <linux/crc16.h> |
42 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
43 | 42 | ||
43 | #include <linux/kthread.h> | ||
44 | #include <linux/freezer.h> | ||
45 | |||
44 | #include "ext4.h" | 46 | #include "ext4.h" |
45 | #include "ext4_jbd2.h" | 47 | #include "ext4_jbd2.h" |
46 | #include "xattr.h" | 48 | #include "xattr.h" |
@@ -50,8 +52,11 @@ | |||
50 | #define CREATE_TRACE_POINTS | 52 | #define CREATE_TRACE_POINTS |
51 | #include <trace/events/ext4.h> | 53 | #include <trace/events/ext4.h> |
52 | 54 | ||
53 | struct proc_dir_entry *ext4_proc_root; | 55 | static struct proc_dir_entry *ext4_proc_root; |
54 | static struct kset *ext4_kset; | 56 | static struct kset *ext4_kset; |
57 | struct ext4_lazy_init *ext4_li_info; | ||
58 | struct mutex ext4_li_mtx; | ||
59 | struct ext4_features *ext4_feat; | ||
55 | 60 | ||
56 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, | 61 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, |
57 | unsigned long journal_devnum); | 62 | unsigned long journal_devnum); |
@@ -68,14 +73,16 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); | |||
68 | static int ext4_unfreeze(struct super_block *sb); | 73 | static int ext4_unfreeze(struct super_block *sb); |
69 | static void ext4_write_super(struct super_block *sb); | 74 | static void ext4_write_super(struct super_block *sb); |
70 | static int ext4_freeze(struct super_block *sb); | 75 | static int ext4_freeze(struct super_block *sb); |
71 | static int ext4_get_sb(struct file_system_type *fs_type, int flags, | 76 | static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, |
72 | const char *dev_name, void *data, struct vfsmount *mnt); | 77 | const char *dev_name, void *data); |
78 | static void ext4_destroy_lazyinit_thread(void); | ||
79 | static void ext4_unregister_li_request(struct super_block *sb); | ||
73 | 80 | ||
74 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | 81 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |
75 | static struct file_system_type ext3_fs_type = { | 82 | static struct file_system_type ext3_fs_type = { |
76 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
77 | .name = "ext3", | 84 | .name = "ext3", |
78 | .get_sb = ext4_get_sb, | 85 | .mount = ext4_mount, |
79 | .kill_sb = kill_block_super, | 86 | .kill_sb = kill_block_super, |
80 | .fs_flags = FS_REQUIRES_DEV, | 87 | .fs_flags = FS_REQUIRES_DEV, |
81 | }; | 88 | }; |
@@ -702,13 +709,13 @@ static void ext4_put_super(struct super_block *sb) | |||
702 | struct ext4_super_block *es = sbi->s_es; | 709 | struct ext4_super_block *es = sbi->s_es; |
703 | int i, err; | 710 | int i, err; |
704 | 711 | ||
712 | ext4_unregister_li_request(sb); | ||
705 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | 713 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); |
706 | 714 | ||
707 | flush_workqueue(sbi->dio_unwritten_wq); | 715 | flush_workqueue(sbi->dio_unwritten_wq); |
708 | destroy_workqueue(sbi->dio_unwritten_wq); | 716 | destroy_workqueue(sbi->dio_unwritten_wq); |
709 | 717 | ||
710 | lock_super(sb); | 718 | lock_super(sb); |
711 | lock_kernel(); | ||
712 | if (sb->s_dirt) | 719 | if (sb->s_dirt) |
713 | ext4_commit_super(sb, 1); | 720 | ext4_commit_super(sb, 1); |
714 | 721 | ||
@@ -719,6 +726,7 @@ static void ext4_put_super(struct super_block *sb) | |||
719 | ext4_abort(sb, "Couldn't clean up the journal"); | 726 | ext4_abort(sb, "Couldn't clean up the journal"); |
720 | } | 727 | } |
721 | 728 | ||
729 | del_timer(&sbi->s_err_report); | ||
722 | ext4_release_system_zone(sb); | 730 | ext4_release_system_zone(sb); |
723 | ext4_mb_release(sb); | 731 | ext4_mb_release(sb); |
724 | ext4_ext_release(sb); | 732 | ext4_ext_release(sb); |
@@ -775,7 +783,6 @@ static void ext4_put_super(struct super_block *sb) | |||
775 | * Now that we are completely done shutting down the | 783 | * Now that we are completely done shutting down the |
776 | * superblock, we need to actually destroy the kobject. | 784 | * superblock, we need to actually destroy the kobject. |
777 | */ | 785 | */ |
778 | unlock_kernel(); | ||
779 | unlock_super(sb); | 786 | unlock_super(sb); |
780 | kobject_put(&sbi->s_kobj); | 787 | kobject_put(&sbi->s_kobj); |
781 | wait_for_completion(&sbi->s_kobj_unregister); | 788 | wait_for_completion(&sbi->s_kobj_unregister); |
@@ -821,12 +828,22 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
821 | ei->cur_aio_dio = NULL; | 828 | ei->cur_aio_dio = NULL; |
822 | ei->i_sync_tid = 0; | 829 | ei->i_sync_tid = 0; |
823 | ei->i_datasync_tid = 0; | 830 | ei->i_datasync_tid = 0; |
831 | atomic_set(&ei->i_ioend_count, 0); | ||
824 | 832 | ||
825 | return &ei->vfs_inode; | 833 | return &ei->vfs_inode; |
826 | } | 834 | } |
827 | 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 | |||
828 | static void ext4_destroy_inode(struct inode *inode) | 844 | static void ext4_destroy_inode(struct inode *inode) |
829 | { | 845 | { |
846 | ext4_ioend_wait(inode); | ||
830 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | 847 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
831 | ext4_msg(inode->i_sb, KERN_ERR, | 848 | ext4_msg(inode->i_sb, KERN_ERR, |
832 | "Inode %lu (%p): orphan list check failed!", | 849 | "Inode %lu (%p): orphan list check failed!", |
@@ -1045,6 +1062,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1045 | !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY)) | 1062 | !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY)) |
1046 | seq_puts(seq, ",block_validity"); | 1063 | seq_puts(seq, ",block_validity"); |
1047 | 1064 | ||
1065 | if (!test_opt(sb, INIT_INODE_TABLE)) | ||
1066 | seq_puts(seq, ",noinit_inode_table"); | ||
1067 | else if (sbi->s_li_wait_mult) | ||
1068 | seq_printf(seq, ",init_inode_table=%u", | ||
1069 | (unsigned) sbi->s_li_wait_mult); | ||
1070 | |||
1048 | ext4_show_quota_options(seq, sb); | 1071 | ext4_show_quota_options(seq, sb); |
1049 | 1072 | ||
1050 | return 0; | 1073 | return 0; |
@@ -1160,6 +1183,7 @@ static const struct super_operations ext4_sops = { | |||
1160 | .destroy_inode = ext4_destroy_inode, | 1183 | .destroy_inode = ext4_destroy_inode, |
1161 | .write_inode = ext4_write_inode, | 1184 | .write_inode = ext4_write_inode, |
1162 | .dirty_inode = ext4_dirty_inode, | 1185 | .dirty_inode = ext4_dirty_inode, |
1186 | .drop_inode = ext4_drop_inode, | ||
1163 | .evict_inode = ext4_evict_inode, | 1187 | .evict_inode = ext4_evict_inode, |
1164 | .put_super = ext4_put_super, | 1188 | .put_super = ext4_put_super, |
1165 | .sync_fs = ext4_sync_fs, | 1189 | .sync_fs = ext4_sync_fs, |
@@ -1173,6 +1197,7 @@ static const struct super_operations ext4_sops = { | |||
1173 | .quota_write = ext4_quota_write, | 1197 | .quota_write = ext4_quota_write, |
1174 | #endif | 1198 | #endif |
1175 | .bdev_try_to_free_page = bdev_try_to_free_page, | 1199 | .bdev_try_to_free_page = bdev_try_to_free_page, |
1200 | .trim_fs = ext4_trim_fs | ||
1176 | }; | 1201 | }; |
1177 | 1202 | ||
1178 | static const struct super_operations ext4_nojournal_sops = { | 1203 | static const struct super_operations ext4_nojournal_sops = { |
@@ -1180,6 +1205,7 @@ static const struct super_operations ext4_nojournal_sops = { | |||
1180 | .destroy_inode = ext4_destroy_inode, | 1205 | .destroy_inode = ext4_destroy_inode, |
1181 | .write_inode = ext4_write_inode, | 1206 | .write_inode = ext4_write_inode, |
1182 | .dirty_inode = ext4_dirty_inode, | 1207 | .dirty_inode = ext4_dirty_inode, |
1208 | .drop_inode = ext4_drop_inode, | ||
1183 | .evict_inode = ext4_evict_inode, | 1209 | .evict_inode = ext4_evict_inode, |
1184 | .write_super = ext4_write_super, | 1210 | .write_super = ext4_write_super, |
1185 | .put_super = ext4_put_super, | 1211 | .put_super = ext4_put_super, |
@@ -1219,6 +1245,7 @@ enum { | |||
1219 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1245 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1220 | Opt_dioread_nolock, Opt_dioread_lock, | 1246 | Opt_dioread_nolock, Opt_dioread_lock, |
1221 | Opt_discard, Opt_nodiscard, | 1247 | Opt_discard, Opt_nodiscard, |
1248 | Opt_init_inode_table, Opt_noinit_inode_table, | ||
1222 | }; | 1249 | }; |
1223 | 1250 | ||
1224 | static const match_table_t tokens = { | 1251 | static const match_table_t tokens = { |
@@ -1289,6 +1316,9 @@ static const match_table_t tokens = { | |||
1289 | {Opt_dioread_lock, "dioread_lock"}, | 1316 | {Opt_dioread_lock, "dioread_lock"}, |
1290 | {Opt_discard, "discard"}, | 1317 | {Opt_discard, "discard"}, |
1291 | {Opt_nodiscard, "nodiscard"}, | 1318 | {Opt_nodiscard, "nodiscard"}, |
1319 | {Opt_init_inode_table, "init_itable=%u"}, | ||
1320 | {Opt_init_inode_table, "init_itable"}, | ||
1321 | {Opt_noinit_inode_table, "noinit_itable"}, | ||
1292 | {Opt_err, NULL}, | 1322 | {Opt_err, NULL}, |
1293 | }; | 1323 | }; |
1294 | 1324 | ||
@@ -1759,6 +1789,20 @@ set_qf_format: | |||
1759 | case Opt_dioread_lock: | 1789 | case Opt_dioread_lock: |
1760 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | 1790 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); |
1761 | break; | 1791 | break; |
1792 | case Opt_init_inode_table: | ||
1793 | set_opt(sbi->s_mount_opt, INIT_INODE_TABLE); | ||
1794 | if (args[0].from) { | ||
1795 | if (match_int(&args[0], &option)) | ||
1796 | return 0; | ||
1797 | } else | ||
1798 | option = EXT4_DEF_LI_WAIT_MULT; | ||
1799 | if (option < 0) | ||
1800 | return 0; | ||
1801 | sbi->s_li_wait_mult = option; | ||
1802 | break; | ||
1803 | case Opt_noinit_inode_table: | ||
1804 | clear_opt(sbi->s_mount_opt, INIT_INODE_TABLE); | ||
1805 | break; | ||
1762 | default: | 1806 | default: |
1763 | ext4_msg(sb, KERN_ERR, | 1807 | ext4_msg(sb, KERN_ERR, |
1764 | "Unrecognized mount option \"%s\" " | 1808 | "Unrecognized mount option \"%s\" " |
@@ -1942,7 +1986,8 @@ int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, | |||
1942 | } | 1986 | } |
1943 | 1987 | ||
1944 | /* Called at mount-time, super-block is locked */ | 1988 | /* Called at mount-time, super-block is locked */ |
1945 | static int ext4_check_descriptors(struct super_block *sb) | 1989 | static int ext4_check_descriptors(struct super_block *sb, |
1990 | ext4_group_t *first_not_zeroed) | ||
1946 | { | 1991 | { |
1947 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1992 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1948 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 1993 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
@@ -1951,7 +1996,7 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1951 | ext4_fsblk_t inode_bitmap; | 1996 | ext4_fsblk_t inode_bitmap; |
1952 | ext4_fsblk_t inode_table; | 1997 | ext4_fsblk_t inode_table; |
1953 | int flexbg_flag = 0; | 1998 | int flexbg_flag = 0; |
1954 | ext4_group_t i; | 1999 | ext4_group_t i, grp = sbi->s_groups_count; |
1955 | 2000 | ||
1956 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | 2001 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) |
1957 | flexbg_flag = 1; | 2002 | flexbg_flag = 1; |
@@ -1967,6 +2012,10 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1967 | last_block = first_block + | 2012 | last_block = first_block + |
1968 | (EXT4_BLOCKS_PER_GROUP(sb) - 1); | 2013 | (EXT4_BLOCKS_PER_GROUP(sb) - 1); |
1969 | 2014 | ||
2015 | if ((grp == sbi->s_groups_count) && | ||
2016 | !(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) | ||
2017 | grp = i; | ||
2018 | |||
1970 | block_bitmap = ext4_block_bitmap(sb, gdp); | 2019 | block_bitmap = ext4_block_bitmap(sb, gdp); |
1971 | if (block_bitmap < first_block || block_bitmap > last_block) { | 2020 | if (block_bitmap < first_block || block_bitmap > last_block) { |
1972 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2021 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
@@ -2004,6 +2053,8 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
2004 | if (!flexbg_flag) | 2053 | if (!flexbg_flag) |
2005 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | 2054 | first_block += EXT4_BLOCKS_PER_GROUP(sb); |
2006 | } | 2055 | } |
2056 | if (NULL != first_not_zeroed) | ||
2057 | *first_not_zeroed = grp; | ||
2007 | 2058 | ||
2008 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); | 2059 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); |
2009 | sbi->s_es->s_free_inodes_count =cpu_to_le32(ext4_count_free_inodes(sb)); | 2060 | sbi->s_es->s_free_inodes_count =cpu_to_le32(ext4_count_free_inodes(sb)); |
@@ -2376,6 +2427,7 @@ static struct ext4_attr ext4_attr_##_name = { \ | |||
2376 | #define EXT4_ATTR(name, mode, show, store) \ | 2427 | #define EXT4_ATTR(name, mode, show, store) \ |
2377 | static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) | 2428 | static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) |
2378 | 2429 | ||
2430 | #define EXT4_INFO_ATTR(name) EXT4_ATTR(name, 0444, NULL, NULL) | ||
2379 | #define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL) | 2431 | #define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL) |
2380 | #define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store) | 2432 | #define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store) |
2381 | #define EXT4_RW_ATTR_SBI_UI(name, elname) \ | 2433 | #define EXT4_RW_ATTR_SBI_UI(name, elname) \ |
@@ -2412,6 +2464,16 @@ static struct attribute *ext4_attrs[] = { | |||
2412 | NULL, | 2464 | NULL, |
2413 | }; | 2465 | }; |
2414 | 2466 | ||
2467 | /* Features this copy of ext4 supports */ | ||
2468 | EXT4_INFO_ATTR(lazy_itable_init); | ||
2469 | EXT4_INFO_ATTR(batched_discard); | ||
2470 | |||
2471 | static struct attribute *ext4_feat_attrs[] = { | ||
2472 | ATTR_LIST(lazy_itable_init), | ||
2473 | ATTR_LIST(batched_discard), | ||
2474 | NULL, | ||
2475 | }; | ||
2476 | |||
2415 | static ssize_t ext4_attr_show(struct kobject *kobj, | 2477 | static ssize_t ext4_attr_show(struct kobject *kobj, |
2416 | struct attribute *attr, char *buf) | 2478 | struct attribute *attr, char *buf) |
2417 | { | 2479 | { |
@@ -2440,7 +2502,6 @@ static void ext4_sb_release(struct kobject *kobj) | |||
2440 | complete(&sbi->s_kobj_unregister); | 2502 | complete(&sbi->s_kobj_unregister); |
2441 | } | 2503 | } |
2442 | 2504 | ||
2443 | |||
2444 | static const struct sysfs_ops ext4_attr_ops = { | 2505 | static const struct sysfs_ops ext4_attr_ops = { |
2445 | .show = ext4_attr_show, | 2506 | .show = ext4_attr_show, |
2446 | .store = ext4_attr_store, | 2507 | .store = ext4_attr_store, |
@@ -2452,6 +2513,17 @@ static struct kobj_type ext4_ktype = { | |||
2452 | .release = ext4_sb_release, | 2513 | .release = ext4_sb_release, |
2453 | }; | 2514 | }; |
2454 | 2515 | ||
2516 | static void ext4_feat_release(struct kobject *kobj) | ||
2517 | { | ||
2518 | complete(&ext4_feat->f_kobj_unregister); | ||
2519 | } | ||
2520 | |||
2521 | static struct kobj_type ext4_feat_ktype = { | ||
2522 | .default_attrs = ext4_feat_attrs, | ||
2523 | .sysfs_ops = &ext4_attr_ops, | ||
2524 | .release = ext4_feat_release, | ||
2525 | }; | ||
2526 | |||
2455 | /* | 2527 | /* |
2456 | * Check whether this filesystem can be mounted based on | 2528 | * Check whether this filesystem can be mounted based on |
2457 | * the features present and the RDONLY/RDWR mount requested. | 2529 | * the features present and the RDONLY/RDWR mount requested. |
@@ -2542,6 +2614,371 @@ static void print_daily_error_info(unsigned long arg) | |||
2542 | mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ); /* Once a day */ | 2614 | mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ); /* Once a day */ |
2543 | } | 2615 | } |
2544 | 2616 | ||
2617 | static void ext4_lazyinode_timeout(unsigned long data) | ||
2618 | { | ||
2619 | struct task_struct *p = (struct task_struct *)data; | ||
2620 | wake_up_process(p); | ||
2621 | } | ||
2622 | |||
2623 | /* Find next suitable group and run ext4_init_inode_table */ | ||
2624 | static int ext4_run_li_request(struct ext4_li_request *elr) | ||
2625 | { | ||
2626 | struct ext4_group_desc *gdp = NULL; | ||
2627 | ext4_group_t group, ngroups; | ||
2628 | struct super_block *sb; | ||
2629 | unsigned long timeout = 0; | ||
2630 | int ret = 0; | ||
2631 | |||
2632 | sb = elr->lr_super; | ||
2633 | ngroups = EXT4_SB(sb)->s_groups_count; | ||
2634 | |||
2635 | for (group = elr->lr_next_group; group < ngroups; group++) { | ||
2636 | gdp = ext4_get_group_desc(sb, group, NULL); | ||
2637 | if (!gdp) { | ||
2638 | ret = 1; | ||
2639 | break; | ||
2640 | } | ||
2641 | |||
2642 | if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) | ||
2643 | break; | ||
2644 | } | ||
2645 | |||
2646 | if (group == ngroups) | ||
2647 | ret = 1; | ||
2648 | |||
2649 | if (!ret) { | ||
2650 | timeout = jiffies; | ||
2651 | ret = ext4_init_inode_table(sb, group, | ||
2652 | elr->lr_timeout ? 0 : 1); | ||
2653 | if (elr->lr_timeout == 0) { | ||
2654 | timeout = jiffies - timeout; | ||
2655 | if (elr->lr_sbi->s_li_wait_mult) | ||
2656 | timeout *= elr->lr_sbi->s_li_wait_mult; | ||
2657 | else | ||
2658 | timeout *= 20; | ||
2659 | elr->lr_timeout = timeout; | ||
2660 | } | ||
2661 | elr->lr_next_sched = jiffies + elr->lr_timeout; | ||
2662 | elr->lr_next_group = group + 1; | ||
2663 | } | ||
2664 | |||
2665 | return ret; | ||
2666 | } | ||
2667 | |||
2668 | /* | ||
2669 | * Remove lr_request from the list_request and free the | ||
2670 | * request tructure. Should be called with li_list_mtx held | ||
2671 | */ | ||
2672 | static void ext4_remove_li_request(struct ext4_li_request *elr) | ||
2673 | { | ||
2674 | struct ext4_sb_info *sbi; | ||
2675 | |||
2676 | if (!elr) | ||
2677 | return; | ||
2678 | |||
2679 | sbi = elr->lr_sbi; | ||
2680 | |||
2681 | list_del(&elr->lr_request); | ||
2682 | sbi->s_li_request = NULL; | ||
2683 | kfree(elr); | ||
2684 | } | ||
2685 | |||
2686 | static void ext4_unregister_li_request(struct super_block *sb) | ||
2687 | { | ||
2688 | struct ext4_li_request *elr = EXT4_SB(sb)->s_li_request; | ||
2689 | |||
2690 | if (!ext4_li_info) | ||
2691 | return; | ||
2692 | |||
2693 | mutex_lock(&ext4_li_info->li_list_mtx); | ||
2694 | ext4_remove_li_request(elr); | ||
2695 | mutex_unlock(&ext4_li_info->li_list_mtx); | ||
2696 | } | ||
2697 | |||
2698 | /* | ||
2699 | * This is the function where ext4lazyinit thread lives. It walks | ||
2700 | * through the request list searching for next scheduled filesystem. | ||
2701 | * When such a fs is found, run the lazy initialization request | ||
2702 | * (ext4_rn_li_request) and keep track of the time spend in this | ||
2703 | * function. Based on that time we compute next schedule time of | ||
2704 | * the request. When walking through the list is complete, compute | ||
2705 | * next waking time and put itself into sleep. | ||
2706 | */ | ||
2707 | static int ext4_lazyinit_thread(void *arg) | ||
2708 | { | ||
2709 | struct ext4_lazy_init *eli = (struct ext4_lazy_init *)arg; | ||
2710 | struct list_head *pos, *n; | ||
2711 | struct ext4_li_request *elr; | ||
2712 | unsigned long next_wakeup; | ||
2713 | DEFINE_WAIT(wait); | ||
2714 | |||
2715 | BUG_ON(NULL == eli); | ||
2716 | |||
2717 | eli->li_timer.data = (unsigned long)current; | ||
2718 | eli->li_timer.function = ext4_lazyinode_timeout; | ||
2719 | |||
2720 | eli->li_task = current; | ||
2721 | wake_up(&eli->li_wait_task); | ||
2722 | |||
2723 | cont_thread: | ||
2724 | while (true) { | ||
2725 | next_wakeup = MAX_JIFFY_OFFSET; | ||
2726 | |||
2727 | mutex_lock(&eli->li_list_mtx); | ||
2728 | if (list_empty(&eli->li_request_list)) { | ||
2729 | mutex_unlock(&eli->li_list_mtx); | ||
2730 | goto exit_thread; | ||
2731 | } | ||
2732 | |||
2733 | list_for_each_safe(pos, n, &eli->li_request_list) { | ||
2734 | elr = list_entry(pos, struct ext4_li_request, | ||
2735 | lr_request); | ||
2736 | |||
2737 | if (time_after_eq(jiffies, elr->lr_next_sched)) { | ||
2738 | if (ext4_run_li_request(elr) != 0) { | ||
2739 | /* error, remove the lazy_init job */ | ||
2740 | ext4_remove_li_request(elr); | ||
2741 | continue; | ||
2742 | } | ||
2743 | } | ||
2744 | |||
2745 | if (time_before(elr->lr_next_sched, next_wakeup)) | ||
2746 | next_wakeup = elr->lr_next_sched; | ||
2747 | } | ||
2748 | mutex_unlock(&eli->li_list_mtx); | ||
2749 | |||
2750 | if (freezing(current)) | ||
2751 | refrigerator(); | ||
2752 | |||
2753 | if ((time_after_eq(jiffies, next_wakeup)) || | ||
2754 | (MAX_JIFFY_OFFSET == next_wakeup)) { | ||
2755 | cond_resched(); | ||
2756 | continue; | ||
2757 | } | ||
2758 | |||
2759 | eli->li_timer.expires = next_wakeup; | ||
2760 | add_timer(&eli->li_timer); | ||
2761 | prepare_to_wait(&eli->li_wait_daemon, &wait, | ||
2762 | TASK_INTERRUPTIBLE); | ||
2763 | if (time_before(jiffies, next_wakeup)) | ||
2764 | schedule(); | ||
2765 | finish_wait(&eli->li_wait_daemon, &wait); | ||
2766 | } | ||
2767 | |||
2768 | exit_thread: | ||
2769 | /* | ||
2770 | * It looks like the request list is empty, but we need | ||
2771 | * to check it under the li_list_mtx lock, to prevent any | ||
2772 | * additions into it, and of course we should lock ext4_li_mtx | ||
2773 | * to atomically free the list and ext4_li_info, because at | ||
2774 | * this point another ext4 filesystem could be registering | ||
2775 | * new one. | ||
2776 | */ | ||
2777 | mutex_lock(&ext4_li_mtx); | ||
2778 | mutex_lock(&eli->li_list_mtx); | ||
2779 | if (!list_empty(&eli->li_request_list)) { | ||
2780 | mutex_unlock(&eli->li_list_mtx); | ||
2781 | mutex_unlock(&ext4_li_mtx); | ||
2782 | goto cont_thread; | ||
2783 | } | ||
2784 | mutex_unlock(&eli->li_list_mtx); | ||
2785 | del_timer_sync(&ext4_li_info->li_timer); | ||
2786 | eli->li_task = NULL; | ||
2787 | wake_up(&eli->li_wait_task); | ||
2788 | |||
2789 | kfree(ext4_li_info); | ||
2790 | ext4_li_info = NULL; | ||
2791 | mutex_unlock(&ext4_li_mtx); | ||
2792 | |||
2793 | return 0; | ||
2794 | } | ||
2795 | |||
2796 | static void ext4_clear_request_list(void) | ||
2797 | { | ||
2798 | struct list_head *pos, *n; | ||
2799 | struct ext4_li_request *elr; | ||
2800 | |||
2801 | mutex_lock(&ext4_li_info->li_list_mtx); | ||
2802 | if (list_empty(&ext4_li_info->li_request_list)) | ||
2803 | return; | ||
2804 | |||
2805 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { | ||
2806 | elr = list_entry(pos, struct ext4_li_request, | ||
2807 | lr_request); | ||
2808 | ext4_remove_li_request(elr); | ||
2809 | } | ||
2810 | mutex_unlock(&ext4_li_info->li_list_mtx); | ||
2811 | } | ||
2812 | |||
2813 | static int ext4_run_lazyinit_thread(void) | ||
2814 | { | ||
2815 | struct task_struct *t; | ||
2816 | |||
2817 | t = kthread_run(ext4_lazyinit_thread, ext4_li_info, "ext4lazyinit"); | ||
2818 | if (IS_ERR(t)) { | ||
2819 | int err = PTR_ERR(t); | ||
2820 | ext4_clear_request_list(); | ||
2821 | del_timer_sync(&ext4_li_info->li_timer); | ||
2822 | kfree(ext4_li_info); | ||
2823 | ext4_li_info = NULL; | ||
2824 | printk(KERN_CRIT "EXT4: error %d creating inode table " | ||
2825 | "initialization thread\n", | ||
2826 | err); | ||
2827 | return err; | ||
2828 | } | ||
2829 | ext4_li_info->li_state |= EXT4_LAZYINIT_RUNNING; | ||
2830 | |||
2831 | wait_event(ext4_li_info->li_wait_task, ext4_li_info->li_task != NULL); | ||
2832 | return 0; | ||
2833 | } | ||
2834 | |||
2835 | /* | ||
2836 | * Check whether it make sense to run itable init. thread or not. | ||
2837 | * If there is at least one uninitialized inode table, return | ||
2838 | * corresponding group number, else the loop goes through all | ||
2839 | * groups and return total number of groups. | ||
2840 | */ | ||
2841 | static ext4_group_t ext4_has_uninit_itable(struct super_block *sb) | ||
2842 | { | ||
2843 | ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count; | ||
2844 | struct ext4_group_desc *gdp = NULL; | ||
2845 | |||
2846 | for (group = 0; group < ngroups; group++) { | ||
2847 | gdp = ext4_get_group_desc(sb, group, NULL); | ||
2848 | if (!gdp) | ||
2849 | continue; | ||
2850 | |||
2851 | if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) | ||
2852 | break; | ||
2853 | } | ||
2854 | |||
2855 | return group; | ||
2856 | } | ||
2857 | |||
2858 | static int ext4_li_info_new(void) | ||
2859 | { | ||
2860 | struct ext4_lazy_init *eli = NULL; | ||
2861 | |||
2862 | eli = kzalloc(sizeof(*eli), GFP_KERNEL); | ||
2863 | if (!eli) | ||
2864 | return -ENOMEM; | ||
2865 | |||
2866 | eli->li_task = NULL; | ||
2867 | INIT_LIST_HEAD(&eli->li_request_list); | ||
2868 | mutex_init(&eli->li_list_mtx); | ||
2869 | |||
2870 | init_waitqueue_head(&eli->li_wait_daemon); | ||
2871 | init_waitqueue_head(&eli->li_wait_task); | ||
2872 | init_timer(&eli->li_timer); | ||
2873 | eli->li_state |= EXT4_LAZYINIT_QUIT; | ||
2874 | |||
2875 | ext4_li_info = eli; | ||
2876 | |||
2877 | return 0; | ||
2878 | } | ||
2879 | |||
2880 | static struct ext4_li_request *ext4_li_request_new(struct super_block *sb, | ||
2881 | ext4_group_t start) | ||
2882 | { | ||
2883 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
2884 | struct ext4_li_request *elr; | ||
2885 | unsigned long rnd; | ||
2886 | |||
2887 | elr = kzalloc(sizeof(*elr), GFP_KERNEL); | ||
2888 | if (!elr) | ||
2889 | return NULL; | ||
2890 | |||
2891 | elr->lr_super = sb; | ||
2892 | elr->lr_sbi = sbi; | ||
2893 | elr->lr_next_group = start; | ||
2894 | |||
2895 | /* | ||
2896 | * Randomize first schedule time of the request to | ||
2897 | * spread the inode table initialization requests | ||
2898 | * better. | ||
2899 | */ | ||
2900 | get_random_bytes(&rnd, sizeof(rnd)); | ||
2901 | elr->lr_next_sched = jiffies + (unsigned long)rnd % | ||
2902 | (EXT4_DEF_LI_MAX_START_DELAY * HZ); | ||
2903 | |||
2904 | return elr; | ||
2905 | } | ||
2906 | |||
2907 | static int ext4_register_li_request(struct super_block *sb, | ||
2908 | ext4_group_t first_not_zeroed) | ||
2909 | { | ||
2910 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
2911 | struct ext4_li_request *elr; | ||
2912 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | ||
2913 | int ret; | ||
2914 | |||
2915 | if (sbi->s_li_request != NULL) | ||
2916 | return 0; | ||
2917 | |||
2918 | if (first_not_zeroed == ngroups || | ||
2919 | (sb->s_flags & MS_RDONLY) || | ||
2920 | !test_opt(sb, INIT_INODE_TABLE)) { | ||
2921 | sbi->s_li_request = NULL; | ||
2922 | return 0; | ||
2923 | } | ||
2924 | |||
2925 | if (first_not_zeroed == ngroups) { | ||
2926 | sbi->s_li_request = NULL; | ||
2927 | return 0; | ||
2928 | } | ||
2929 | |||
2930 | elr = ext4_li_request_new(sb, first_not_zeroed); | ||
2931 | if (!elr) | ||
2932 | return -ENOMEM; | ||
2933 | |||
2934 | mutex_lock(&ext4_li_mtx); | ||
2935 | |||
2936 | if (NULL == ext4_li_info) { | ||
2937 | ret = ext4_li_info_new(); | ||
2938 | if (ret) | ||
2939 | goto out; | ||
2940 | } | ||
2941 | |||
2942 | mutex_lock(&ext4_li_info->li_list_mtx); | ||
2943 | list_add(&elr->lr_request, &ext4_li_info->li_request_list); | ||
2944 | mutex_unlock(&ext4_li_info->li_list_mtx); | ||
2945 | |||
2946 | sbi->s_li_request = elr; | ||
2947 | |||
2948 | if (!(ext4_li_info->li_state & EXT4_LAZYINIT_RUNNING)) { | ||
2949 | ret = ext4_run_lazyinit_thread(); | ||
2950 | if (ret) | ||
2951 | goto out; | ||
2952 | } | ||
2953 | out: | ||
2954 | mutex_unlock(&ext4_li_mtx); | ||
2955 | if (ret) | ||
2956 | kfree(elr); | ||
2957 | return ret; | ||
2958 | } | ||
2959 | |||
2960 | /* | ||
2961 | * We do not need to lock anything since this is called on | ||
2962 | * module unload. | ||
2963 | */ | ||
2964 | static void ext4_destroy_lazyinit_thread(void) | ||
2965 | { | ||
2966 | /* | ||
2967 | * If thread exited earlier | ||
2968 | * there's nothing to be done. | ||
2969 | */ | ||
2970 | if (!ext4_li_info) | ||
2971 | return; | ||
2972 | |||
2973 | ext4_clear_request_list(); | ||
2974 | |||
2975 | while (ext4_li_info->li_task) { | ||
2976 | wake_up(&ext4_li_info->li_wait_daemon); | ||
2977 | wait_event(ext4_li_info->li_wait_task, | ||
2978 | ext4_li_info->li_task == NULL); | ||
2979 | } | ||
2980 | } | ||
2981 | |||
2545 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) | 2982 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
2546 | __releases(kernel_lock) | 2983 | __releases(kernel_lock) |
2547 | __acquires(kernel_lock) | 2984 | __acquires(kernel_lock) |
@@ -2567,6 +3004,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2567 | __u64 blocks_count; | 3004 | __u64 blocks_count; |
2568 | int err; | 3005 | int err; |
2569 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; | 3006 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; |
3007 | ext4_group_t first_not_zeroed; | ||
2570 | 3008 | ||
2571 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 3009 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
2572 | if (!sbi) | 3010 | if (!sbi) |
@@ -2588,8 +3026,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2588 | sbi->s_sectors_written_start = | 3026 | sbi->s_sectors_written_start = |
2589 | part_stat_read(sb->s_bdev->bd_part, sectors[1]); | 3027 | part_stat_read(sb->s_bdev->bd_part, sectors[1]); |
2590 | 3028 | ||
2591 | unlock_kernel(); | ||
2592 | |||
2593 | /* Cleanup superblock name */ | 3029 | /* Cleanup superblock name */ |
2594 | for (cp = sb->s_id; (cp = strchr(cp, '/'));) | 3030 | for (cp = sb->s_id; (cp = strchr(cp, '/'));) |
2595 | *cp = '!'; | 3031 | *cp = '!'; |
@@ -2629,6 +3065,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2629 | 3065 | ||
2630 | /* Set defaults before we parse the mount options */ | 3066 | /* Set defaults before we parse the mount options */ |
2631 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | 3067 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); |
3068 | set_opt(sbi->s_mount_opt, INIT_INODE_TABLE); | ||
2632 | if (def_mount_opts & EXT4_DEFM_DEBUG) | 3069 | if (def_mount_opts & EXT4_DEFM_DEBUG) |
2633 | set_opt(sbi->s_mount_opt, DEBUG); | 3070 | set_opt(sbi->s_mount_opt, DEBUG); |
2634 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { | 3071 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { |
@@ -2906,7 +3343,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2906 | goto failed_mount2; | 3343 | goto failed_mount2; |
2907 | } | 3344 | } |
2908 | } | 3345 | } |
2909 | if (!ext4_check_descriptors(sb)) { | 3346 | if (!ext4_check_descriptors(sb, &first_not_zeroed)) { |
2910 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); | 3347 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); |
2911 | goto failed_mount2; | 3348 | goto failed_mount2; |
2912 | } | 3349 | } |
@@ -2922,6 +3359,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2922 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 3359 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
2923 | spin_lock_init(&sbi->s_next_gen_lock); | 3360 | spin_lock_init(&sbi->s_next_gen_lock); |
2924 | 3361 | ||
3362 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | ||
3363 | ext4_count_free_blocks(sb)); | ||
3364 | if (!err) { | ||
3365 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
3366 | ext4_count_free_inodes(sb)); | ||
3367 | } | ||
3368 | if (!err) { | ||
3369 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
3370 | ext4_count_dirs(sb)); | ||
3371 | } | ||
3372 | if (!err) { | ||
3373 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | ||
3374 | } | ||
3375 | if (err) { | ||
3376 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3377 | goto failed_mount3; | ||
3378 | } | ||
3379 | |||
2925 | sbi->s_stripe = ext4_get_stripe_size(sbi); | 3380 | sbi->s_stripe = ext4_get_stripe_size(sbi); |
2926 | sbi->s_max_writeback_mb_bump = 128; | 3381 | sbi->s_max_writeback_mb_bump = 128; |
2927 | 3382 | ||
@@ -3020,22 +3475,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3020 | } | 3475 | } |
3021 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 3476 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
3022 | 3477 | ||
3023 | no_journal: | 3478 | /* |
3024 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | 3479 | * The journal may have updated the bg summary counts, so we |
3025 | ext4_count_free_blocks(sb)); | 3480 | * need to update the global counters. |
3026 | if (!err) | 3481 | */ |
3027 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | 3482 | percpu_counter_set(&sbi->s_freeblocks_counter, |
3028 | ext4_count_free_inodes(sb)); | 3483 | ext4_count_free_blocks(sb)); |
3029 | if (!err) | 3484 | percpu_counter_set(&sbi->s_freeinodes_counter, |
3030 | err = percpu_counter_init(&sbi->s_dirs_counter, | 3485 | ext4_count_free_inodes(sb)); |
3031 | ext4_count_dirs(sb)); | 3486 | percpu_counter_set(&sbi->s_dirs_counter, |
3032 | if (!err) | 3487 | ext4_count_dirs(sb)); |
3033 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | 3488 | percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); |
3034 | if (err) { | ||
3035 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3036 | goto failed_mount_wq; | ||
3037 | } | ||
3038 | 3489 | ||
3490 | no_journal: | ||
3039 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 3491 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
3040 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 3492 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
3041 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); | 3493 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); |
@@ -3127,6 +3579,10 @@ no_journal: | |||
3127 | goto failed_mount4; | 3579 | goto failed_mount4; |
3128 | } | 3580 | } |
3129 | 3581 | ||
3582 | err = ext4_register_li_request(sb, first_not_zeroed); | ||
3583 | if (err) | ||
3584 | goto failed_mount4; | ||
3585 | |||
3130 | sbi->s_kobj.kset = ext4_kset; | 3586 | sbi->s_kobj.kset = ext4_kset; |
3131 | init_completion(&sbi->s_kobj_unregister); | 3587 | init_completion(&sbi->s_kobj_unregister); |
3132 | err = kobject_init_and_add(&sbi->s_kobj, &ext4_ktype, NULL, | 3588 | err = kobject_init_and_add(&sbi->s_kobj, &ext4_ktype, NULL, |
@@ -3164,7 +3620,6 @@ no_journal: | |||
3164 | if (es->s_error_count) | 3620 | if (es->s_error_count) |
3165 | mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */ | 3621 | mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */ |
3166 | 3622 | ||
3167 | lock_kernel(); | ||
3168 | kfree(orig_data); | 3623 | kfree(orig_data); |
3169 | return 0; | 3624 | return 0; |
3170 | 3625 | ||
@@ -3182,10 +3637,6 @@ failed_mount_wq: | |||
3182 | jbd2_journal_destroy(sbi->s_journal); | 3637 | jbd2_journal_destroy(sbi->s_journal); |
3183 | sbi->s_journal = NULL; | 3638 | sbi->s_journal = NULL; |
3184 | } | 3639 | } |
3185 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3186 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3187 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3188 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3189 | failed_mount3: | 3640 | failed_mount3: |
3190 | if (sbi->s_flex_groups) { | 3641 | if (sbi->s_flex_groups) { |
3191 | if (is_vmalloc_addr(sbi->s_flex_groups)) | 3642 | if (is_vmalloc_addr(sbi->s_flex_groups)) |
@@ -3193,6 +3644,10 @@ failed_mount3: | |||
3193 | else | 3644 | else |
3194 | kfree(sbi->s_flex_groups); | 3645 | kfree(sbi->s_flex_groups); |
3195 | } | 3646 | } |
3647 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3648 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3649 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3650 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3196 | failed_mount2: | 3651 | failed_mount2: |
3197 | for (i = 0; i < db_count; i++) | 3652 | for (i = 0; i < db_count; i++) |
3198 | brelse(sbi->s_group_desc[i]); | 3653 | brelse(sbi->s_group_desc[i]); |
@@ -3211,7 +3666,6 @@ out_fail: | |||
3211 | sb->s_fs_info = NULL; | 3666 | sb->s_fs_info = NULL; |
3212 | kfree(sbi->s_blockgroup_lock); | 3667 | kfree(sbi->s_blockgroup_lock); |
3213 | kfree(sbi); | 3668 | kfree(sbi); |
3214 | lock_kernel(); | ||
3215 | out_free_orig: | 3669 | out_free_orig: |
3216 | kfree(orig_data); | 3670 | kfree(orig_data); |
3217 | return ret; | 3671 | return ret; |
@@ -3468,7 +3922,7 @@ static int ext4_load_journal(struct super_block *sb, | |||
3468 | EXT4_SB(sb)->s_journal = journal; | 3922 | EXT4_SB(sb)->s_journal = journal; |
3469 | ext4_clear_journal_err(sb, es); | 3923 | ext4_clear_journal_err(sb, es); |
3470 | 3924 | ||
3471 | if (journal_devnum && | 3925 | if (!really_read_only && journal_devnum && |
3472 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { | 3926 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { |
3473 | es->s_journal_dev = cpu_to_le32(journal_devnum); | 3927 | es->s_journal_dev = cpu_to_le32(journal_devnum); |
3474 | 3928 | ||
@@ -3522,9 +3976,10 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
3522 | es->s_kbytes_written = | 3976 | es->s_kbytes_written = |
3523 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); | 3977 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); |
3524 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( | 3978 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( |
3525 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3979 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3526 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( | 3980 | es->s_free_inodes_count = |
3527 | &EXT4_SB(sb)->s_freeinodes_counter)); | 3981 | cpu_to_le32(percpu_counter_sum_positive( |
3982 | &EXT4_SB(sb)->s_freeinodes_counter)); | ||
3528 | sb->s_dirt = 0; | 3983 | sb->s_dirt = 0; |
3529 | BUFFER_TRACE(sbh, "marking dirty"); | 3984 | BUFFER_TRACE(sbh, "marking dirty"); |
3530 | mark_buffer_dirty(sbh); | 3985 | mark_buffer_dirty(sbh); |
@@ -3720,8 +4175,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3720 | #endif | 4175 | #endif |
3721 | char *orig_data = kstrdup(data, GFP_KERNEL); | 4176 | char *orig_data = kstrdup(data, GFP_KERNEL); |
3722 | 4177 | ||
3723 | lock_kernel(); | ||
3724 | |||
3725 | /* Store the original options */ | 4178 | /* Store the original options */ |
3726 | lock_super(sb); | 4179 | lock_super(sb); |
3727 | old_sb_flags = sb->s_flags; | 4180 | old_sb_flags = sb->s_flags; |
@@ -3844,6 +4297,19 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3844 | enable_quota = 1; | 4297 | enable_quota = 1; |
3845 | } | 4298 | } |
3846 | } | 4299 | } |
4300 | |||
4301 | /* | ||
4302 | * Reinitialize lazy itable initialization thread based on | ||
4303 | * current settings | ||
4304 | */ | ||
4305 | if ((sb->s_flags & MS_RDONLY) || !test_opt(sb, INIT_INODE_TABLE)) | ||
4306 | ext4_unregister_li_request(sb); | ||
4307 | else { | ||
4308 | ext4_group_t first_not_zeroed; | ||
4309 | first_not_zeroed = ext4_has_uninit_itable(sb); | ||
4310 | ext4_register_li_request(sb, first_not_zeroed); | ||
4311 | } | ||
4312 | |||
3847 | ext4_setup_system_zone(sb); | 4313 | ext4_setup_system_zone(sb); |
3848 | if (sbi->s_journal == NULL) | 4314 | if (sbi->s_journal == NULL) |
3849 | ext4_commit_super(sb, 1); | 4315 | ext4_commit_super(sb, 1); |
@@ -3856,7 +4322,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3856 | kfree(old_opts.s_qf_names[i]); | 4322 | kfree(old_opts.s_qf_names[i]); |
3857 | #endif | 4323 | #endif |
3858 | unlock_super(sb); | 4324 | unlock_super(sb); |
3859 | unlock_kernel(); | ||
3860 | if (enable_quota) | 4325 | if (enable_quota) |
3861 | dquot_resume(sb, -1); | 4326 | dquot_resume(sb, -1); |
3862 | 4327 | ||
@@ -3882,7 +4347,6 @@ restore_opts: | |||
3882 | } | 4347 | } |
3883 | #endif | 4348 | #endif |
3884 | unlock_super(sb); | 4349 | unlock_super(sb); |
3885 | unlock_kernel(); | ||
3886 | kfree(orig_data); | 4350 | kfree(orig_data); |
3887 | return err; | 4351 | return err; |
3888 | } | 4352 | } |
@@ -4116,12 +4580,10 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
4116 | 4580 | ||
4117 | static int ext4_quota_off(struct super_block *sb, int type) | 4581 | static int ext4_quota_off(struct super_block *sb, int type) |
4118 | { | 4582 | { |
4119 | /* Force all delayed allocation blocks to be allocated */ | 4583 | /* Force all delayed allocation blocks to be allocated. |
4120 | if (test_opt(sb, DELALLOC)) { | 4584 | * Caller already holds s_umount sem */ |
4121 | down_read(&sb->s_umount); | 4585 | if (test_opt(sb, DELALLOC)) |
4122 | sync_filesystem(sb); | 4586 | sync_filesystem(sb); |
4123 | up_read(&sb->s_umount); | ||
4124 | } | ||
4125 | 4587 | ||
4126 | return dquot_quota_off(sb, type); | 4588 | return dquot_quota_off(sb, type); |
4127 | } | 4589 | } |
@@ -4227,17 +4689,17 @@ out: | |||
4227 | 4689 | ||
4228 | #endif | 4690 | #endif |
4229 | 4691 | ||
4230 | static int ext4_get_sb(struct file_system_type *fs_type, int flags, | 4692 | static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, |
4231 | const char *dev_name, void *data, struct vfsmount *mnt) | 4693 | const char *dev_name, void *data) |
4232 | { | 4694 | { |
4233 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); | 4695 | return mount_bdev(fs_type, flags, dev_name, data, ext4_fill_super); |
4234 | } | 4696 | } |
4235 | 4697 | ||
4236 | #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | 4698 | #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |
4237 | static struct file_system_type ext2_fs_type = { | 4699 | static struct file_system_type ext2_fs_type = { |
4238 | .owner = THIS_MODULE, | 4700 | .owner = THIS_MODULE, |
4239 | .name = "ext2", | 4701 | .name = "ext2", |
4240 | .get_sb = ext4_get_sb, | 4702 | .mount = ext4_mount, |
4241 | .kill_sb = kill_block_super, | 4703 | .kill_sb = kill_block_super, |
4242 | .fs_flags = FS_REQUIRES_DEV, | 4704 | .fs_flags = FS_REQUIRES_DEV, |
4243 | }; | 4705 | }; |
@@ -4282,28 +4744,58 @@ static inline void unregister_as_ext3(void) { } | |||
4282 | static struct file_system_type ext4_fs_type = { | 4744 | static struct file_system_type ext4_fs_type = { |
4283 | .owner = THIS_MODULE, | 4745 | .owner = THIS_MODULE, |
4284 | .name = "ext4", | 4746 | .name = "ext4", |
4285 | .get_sb = ext4_get_sb, | 4747 | .mount = ext4_mount, |
4286 | .kill_sb = kill_block_super, | 4748 | .kill_sb = kill_block_super, |
4287 | .fs_flags = FS_REQUIRES_DEV, | 4749 | .fs_flags = FS_REQUIRES_DEV, |
4288 | }; | 4750 | }; |
4289 | 4751 | ||
4290 | static int __init init_ext4_fs(void) | 4752 | int __init ext4_init_feat_adverts(void) |
4753 | { | ||
4754 | struct ext4_features *ef; | ||
4755 | int ret = -ENOMEM; | ||
4756 | |||
4757 | ef = kzalloc(sizeof(struct ext4_features), GFP_KERNEL); | ||
4758 | if (!ef) | ||
4759 | goto out; | ||
4760 | |||
4761 | ef->f_kobj.kset = ext4_kset; | ||
4762 | init_completion(&ef->f_kobj_unregister); | ||
4763 | ret = kobject_init_and_add(&ef->f_kobj, &ext4_feat_ktype, NULL, | ||
4764 | "features"); | ||
4765 | if (ret) { | ||
4766 | kfree(ef); | ||
4767 | goto out; | ||
4768 | } | ||
4769 | |||
4770 | ext4_feat = ef; | ||
4771 | ret = 0; | ||
4772 | out: | ||
4773 | return ret; | ||
4774 | } | ||
4775 | |||
4776 | static int __init ext4_init_fs(void) | ||
4291 | { | 4777 | { |
4292 | int err; | 4778 | int err; |
4293 | 4779 | ||
4294 | ext4_check_flag_values(); | 4780 | ext4_check_flag_values(); |
4295 | err = init_ext4_system_zone(); | 4781 | err = ext4_init_pageio(); |
4296 | if (err) | 4782 | if (err) |
4297 | return err; | 4783 | return err; |
4784 | err = ext4_init_system_zone(); | ||
4785 | if (err) | ||
4786 | goto out5; | ||
4298 | ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); | 4787 | ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); |
4299 | if (!ext4_kset) | 4788 | if (!ext4_kset) |
4300 | goto out4; | 4789 | goto out4; |
4301 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); | 4790 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); |
4302 | err = init_ext4_mballoc(); | 4791 | |
4792 | err = ext4_init_feat_adverts(); | ||
4793 | |||
4794 | err = ext4_init_mballoc(); | ||
4303 | if (err) | 4795 | if (err) |
4304 | goto out3; | 4796 | goto out3; |
4305 | 4797 | ||
4306 | err = init_ext4_xattr(); | 4798 | err = ext4_init_xattr(); |
4307 | if (err) | 4799 | if (err) |
4308 | goto out2; | 4800 | goto out2; |
4309 | err = init_inodecache(); | 4801 | err = init_inodecache(); |
@@ -4314,38 +4806,46 @@ static int __init init_ext4_fs(void) | |||
4314 | err = register_filesystem(&ext4_fs_type); | 4806 | err = register_filesystem(&ext4_fs_type); |
4315 | if (err) | 4807 | if (err) |
4316 | goto out; | 4808 | goto out; |
4809 | |||
4810 | ext4_li_info = NULL; | ||
4811 | mutex_init(&ext4_li_mtx); | ||
4317 | return 0; | 4812 | return 0; |
4318 | out: | 4813 | out: |
4319 | unregister_as_ext2(); | 4814 | unregister_as_ext2(); |
4320 | unregister_as_ext3(); | 4815 | unregister_as_ext3(); |
4321 | destroy_inodecache(); | 4816 | destroy_inodecache(); |
4322 | out1: | 4817 | out1: |
4323 | exit_ext4_xattr(); | 4818 | ext4_exit_xattr(); |
4324 | out2: | 4819 | out2: |
4325 | exit_ext4_mballoc(); | 4820 | ext4_exit_mballoc(); |
4326 | out3: | 4821 | out3: |
4822 | kfree(ext4_feat); | ||
4327 | remove_proc_entry("fs/ext4", NULL); | 4823 | remove_proc_entry("fs/ext4", NULL); |
4328 | kset_unregister(ext4_kset); | 4824 | kset_unregister(ext4_kset); |
4329 | out4: | 4825 | out4: |
4330 | exit_ext4_system_zone(); | 4826 | ext4_exit_system_zone(); |
4827 | out5: | ||
4828 | ext4_exit_pageio(); | ||
4331 | return err; | 4829 | return err; |
4332 | } | 4830 | } |
4333 | 4831 | ||
4334 | static void __exit exit_ext4_fs(void) | 4832 | static void __exit ext4_exit_fs(void) |
4335 | { | 4833 | { |
4834 | ext4_destroy_lazyinit_thread(); | ||
4336 | unregister_as_ext2(); | 4835 | unregister_as_ext2(); |
4337 | unregister_as_ext3(); | 4836 | unregister_as_ext3(); |
4338 | unregister_filesystem(&ext4_fs_type); | 4837 | unregister_filesystem(&ext4_fs_type); |
4339 | destroy_inodecache(); | 4838 | destroy_inodecache(); |
4340 | exit_ext4_xattr(); | 4839 | ext4_exit_xattr(); |
4341 | exit_ext4_mballoc(); | 4840 | ext4_exit_mballoc(); |
4342 | remove_proc_entry("fs/ext4", NULL); | 4841 | remove_proc_entry("fs/ext4", NULL); |
4343 | kset_unregister(ext4_kset); | 4842 | kset_unregister(ext4_kset); |
4344 | exit_ext4_system_zone(); | 4843 | ext4_exit_system_zone(); |
4844 | ext4_exit_pageio(); | ||
4345 | } | 4845 | } |
4346 | 4846 | ||
4347 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); | 4847 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); |
4348 | MODULE_DESCRIPTION("Fourth Extended Filesystem"); | 4848 | MODULE_DESCRIPTION("Fourth Extended Filesystem"); |
4349 | MODULE_LICENSE("GPL"); | 4849 | MODULE_LICENSE("GPL"); |
4350 | module_init(init_ext4_fs) | 4850 | module_init(ext4_init_fs) |
4351 | module_exit(exit_ext4_fs) | 4851 | module_exit(ext4_exit_fs) |