aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@macbook.(none)>2009-12-03 01:33:40 -0500
committerJames Morris <jmorris@macbook.(none)>2009-12-03 01:33:40 -0500
commitc84d6efd363a3948eb32ec40d46bab6338580454 (patch)
tree3ba7ac46e6626fe8ac843834588609eb6ccee5c6 /fs/ext4/super.c
parent7539cf4b92be4aecc573ea962135f246a7a33401 (diff)
parent22763c5cf3690a681551162c15d34d935308c8d7 (diff)
Merge branch 'master' into next
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c150
1 files changed, 71 insertions, 79 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index df539ba27779..d4ca92aab514 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -50,13 +50,6 @@
50#define CREATE_TRACE_POINTS 50#define CREATE_TRACE_POINTS
51#include <trace/events/ext4.h> 51#include <trace/events/ext4.h>
52 52
53static int default_mb_history_length = 1000;
54
55module_param_named(default_mb_history_length, default_mb_history_length,
56 int, 0644);
57MODULE_PARM_DESC(default_mb_history_length,
58 "Default number of entries saved for mb_history");
59
60struct proc_dir_entry *ext4_proc_root; 53struct proc_dir_entry *ext4_proc_root;
61static struct kset *ext4_kset; 54static struct kset *ext4_kset;
62 55
@@ -189,6 +182,36 @@ void ext4_itable_unused_set(struct super_block *sb,
189 bg->bg_itable_unused_hi = cpu_to_le16(count >> 16); 182 bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
190} 183}
191 184
185
186/* Just increment the non-pointer handle value */
187static handle_t *ext4_get_nojournal(void)
188{
189 handle_t *handle = current->journal_info;
190 unsigned long ref_cnt = (unsigned long)handle;
191
192 BUG_ON(ref_cnt >= EXT4_NOJOURNAL_MAX_REF_COUNT);
193
194 ref_cnt++;
195 handle = (handle_t *)ref_cnt;
196
197 current->journal_info = handle;
198 return handle;
199}
200
201
202/* Decrement the non-pointer handle value */
203static void ext4_put_nojournal(handle_t *handle)
204{
205 unsigned long ref_cnt = (unsigned long)handle;
206
207 BUG_ON(ref_cnt == 0);
208
209 ref_cnt--;
210 handle = (handle_t *)ref_cnt;
211
212 current->journal_info = handle;
213}
214
192/* 215/*
193 * Wrappers for jbd2_journal_start/end. 216 * Wrappers for jbd2_journal_start/end.
194 * 217 *
@@ -215,11 +238,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
215 } 238 }
216 return jbd2_journal_start(journal, nblocks); 239 return jbd2_journal_start(journal, nblocks);
217 } 240 }
218 /* 241 return ext4_get_nojournal();
219 * We're not journaling, return the appropriate indication.
220 */
221 current->journal_info = EXT4_NOJOURNAL_HANDLE;
222 return current->journal_info;
223} 242}
224 243
225/* 244/*
@@ -235,11 +254,7 @@ int __ext4_journal_stop(const char *where, handle_t *handle)
235 int rc; 254 int rc;
236 255
237 if (!ext4_handle_valid(handle)) { 256 if (!ext4_handle_valid(handle)) {
238 /* 257 ext4_put_nojournal(handle);
239 * Do this here since we don't call jbd2_journal_stop() in
240 * no-journal mode.
241 */
242 current->journal_info = NULL;
243 return 0; 258 return 0;
244 } 259 }
245 sb = handle->h_transaction->t_journal->j_private; 260 sb = handle->h_transaction->t_journal->j_private;
@@ -580,6 +595,9 @@ static void ext4_put_super(struct super_block *sb)
580 struct ext4_super_block *es = sbi->s_es; 595 struct ext4_super_block *es = sbi->s_es;
581 int i, err; 596 int i, err;
582 597
598 flush_workqueue(sbi->dio_unwritten_wq);
599 destroy_workqueue(sbi->dio_unwritten_wq);
600
583 lock_super(sb); 601 lock_super(sb);
584 lock_kernel(); 602 lock_kernel();
585 if (sb->s_dirt) 603 if (sb->s_dirt)
@@ -684,6 +702,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
684 ei->i_allocated_meta_blocks = 0; 702 ei->i_allocated_meta_blocks = 0;
685 ei->i_delalloc_reserved_flag = 0; 703 ei->i_delalloc_reserved_flag = 0;
686 spin_lock_init(&(ei->i_block_reservation_lock)); 704 spin_lock_init(&(ei->i_block_reservation_lock));
705 INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
706 ei->cur_aio_dio = NULL;
687 707
688 return &ei->vfs_inode; 708 return &ei->vfs_inode;
689} 709}
@@ -1052,7 +1072,7 @@ enum {
1052 Opt_journal_update, Opt_journal_dev, 1072 Opt_journal_update, Opt_journal_dev,
1053 Opt_journal_checksum, Opt_journal_async_commit, 1073 Opt_journal_checksum, Opt_journal_async_commit,
1054 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 1074 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
1055 Opt_data_err_abort, Opt_data_err_ignore, Opt_mb_history_length, 1075 Opt_data_err_abort, Opt_data_err_ignore,
1056 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 1076 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
1057 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 1077 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
1058 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, 1078 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
@@ -1099,7 +1119,6 @@ static const match_table_t tokens = {
1099 {Opt_data_writeback, "data=writeback"}, 1119 {Opt_data_writeback, "data=writeback"},
1100 {Opt_data_err_abort, "data_err=abort"}, 1120 {Opt_data_err_abort, "data_err=abort"},
1101 {Opt_data_err_ignore, "data_err=ignore"}, 1121 {Opt_data_err_ignore, "data_err=ignore"},
1102 {Opt_mb_history_length, "mb_history_length=%u"},
1103 {Opt_offusrjquota, "usrjquota="}, 1122 {Opt_offusrjquota, "usrjquota="},
1104 {Opt_usrjquota, "usrjquota=%s"}, 1123 {Opt_usrjquota, "usrjquota=%s"},
1105 {Opt_offgrpjquota, "grpjquota="}, 1124 {Opt_offgrpjquota, "grpjquota="},
@@ -1281,9 +1300,11 @@ static int parse_options(char *options, struct super_block *sb,
1281 *journal_devnum = option; 1300 *journal_devnum = option;
1282 break; 1301 break;
1283 case Opt_journal_checksum: 1302 case Opt_journal_checksum:
1284 break; /* Kept for backwards compatibility */ 1303 set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
1304 break;
1285 case Opt_journal_async_commit: 1305 case Opt_journal_async_commit:
1286 set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT); 1306 set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
1307 set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
1287 break; 1308 break;
1288 case Opt_noload: 1309 case Opt_noload:
1289 set_opt(sbi->s_mount_opt, NOLOAD); 1310 set_opt(sbi->s_mount_opt, NOLOAD);
@@ -1340,13 +1361,6 @@ static int parse_options(char *options, struct super_block *sb,
1340 case Opt_data_err_ignore: 1361 case Opt_data_err_ignore:
1341 clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); 1362 clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
1342 break; 1363 break;
1343 case Opt_mb_history_length:
1344 if (match_int(&args[0], &option))
1345 return 0;
1346 if (option < 0)
1347 return 0;
1348 sbi->s_mb_history_max = option;
1349 break;
1350#ifdef CONFIG_QUOTA 1364#ifdef CONFIG_QUOTA
1351 case Opt_usrjquota: 1365 case Opt_usrjquota:
1352 qtype = USRQUOTA; 1366 qtype = USRQUOTA;
@@ -1646,13 +1660,6 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1646 EXT4_INODES_PER_GROUP(sb), 1660 EXT4_INODES_PER_GROUP(sb),
1647 sbi->s_mount_opt); 1661 sbi->s_mount_opt);
1648 1662
1649 if (EXT4_SB(sb)->s_journal) {
1650 ext4_msg(sb, KERN_INFO, "%s journal on %s",
1651 EXT4_SB(sb)->s_journal->j_inode ? "internal" :
1652 "external", EXT4_SB(sb)->s_journal->j_devname);
1653 } else {
1654 ext4_msg(sb, KERN_INFO, "no journal");
1655 }
1656 return res; 1663 return res;
1657} 1664}
1658 1665
@@ -2197,6 +2204,7 @@ EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
2197EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); 2204EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
2198EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); 2205EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
2199EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); 2206EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
2207EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump);
2200 2208
2201static struct attribute *ext4_attrs[] = { 2209static struct attribute *ext4_attrs[] = {
2202 ATTR_LIST(delayed_allocation_blocks), 2210 ATTR_LIST(delayed_allocation_blocks),
@@ -2210,6 +2218,7 @@ static struct attribute *ext4_attrs[] = {
2210 ATTR_LIST(mb_order2_req), 2218 ATTR_LIST(mb_order2_req),
2211 ATTR_LIST(mb_stream_req), 2219 ATTR_LIST(mb_stream_req),
2212 ATTR_LIST(mb_group_prealloc), 2220 ATTR_LIST(mb_group_prealloc),
2221 ATTR_LIST(max_writeback_mb_bump),
2213 NULL, 2222 NULL,
2214}; 2223};
2215 2224
@@ -2413,7 +2422,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2413 sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; 2422 sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ;
2414 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; 2423 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
2415 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; 2424 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
2416 sbi->s_mb_history_max = default_mb_history_length;
2417 2425
2418 set_opt(sbi->s_mount_opt, BARRIER); 2426 set_opt(sbi->s_mount_opt, BARRIER);
2419 2427
@@ -2679,6 +2687,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2679 } 2687 }
2680 2688
2681 sbi->s_stripe = ext4_get_stripe_size(sbi); 2689 sbi->s_stripe = ext4_get_stripe_size(sbi);
2690 sbi->s_max_writeback_mb_bump = 128;
2682 2691
2683 /* 2692 /*
2684 * set up enough so that it can read an inode 2693 * set up enough so that it can read an inode
@@ -2752,14 +2761,20 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2752 goto failed_mount4; 2761 goto failed_mount4;
2753 } 2762 }
2754 2763
2755 jbd2_journal_set_features(sbi->s_journal, 2764 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
2756 JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0); 2765 jbd2_journal_set_features(sbi->s_journal,
2757 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) 2766 JBD2_FEATURE_COMPAT_CHECKSUM, 0,
2758 jbd2_journal_set_features(sbi->s_journal, 0, 0,
2759 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); 2767 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
2760 else 2768 } else if (test_opt(sb, JOURNAL_CHECKSUM)) {
2769 jbd2_journal_set_features(sbi->s_journal,
2770 JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
2761 jbd2_journal_clear_features(sbi->s_journal, 0, 0, 2771 jbd2_journal_clear_features(sbi->s_journal, 0, 0,
2762 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); 2772 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
2773 } else {
2774 jbd2_journal_clear_features(sbi->s_journal,
2775 JBD2_FEATURE_COMPAT_CHECKSUM, 0,
2776 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
2777 }
2763 2778
2764 /* We have now updated the journal if required, so we can 2779 /* We have now updated the journal if required, so we can
2765 * validate the data journaling mode. */ 2780 * validate the data journaling mode. */
@@ -2798,6 +2813,12 @@ no_journal:
2798 clear_opt(sbi->s_mount_opt, NOBH); 2813 clear_opt(sbi->s_mount_opt, NOBH);
2799 } 2814 }
2800 } 2815 }
2816 EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten");
2817 if (!EXT4_SB(sb)->dio_unwritten_wq) {
2818 printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n");
2819 goto failed_mount_wq;
2820 }
2821
2801 /* 2822 /*
2802 * The jbd2_journal_load will have done any necessary log recovery, 2823 * The jbd2_journal_load will have done any necessary log recovery,
2803 * so we can safely mount the rest of the filesystem now. 2824 * so we can safely mount the rest of the filesystem now.
@@ -2849,12 +2870,12 @@ no_journal:
2849 "available"); 2870 "available");
2850 } 2871 }
2851 2872
2852 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { 2873 if (test_opt(sb, DELALLOC) &&
2874 (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) {
2853 ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - " 2875 ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - "
2854 "requested data journaling mode"); 2876 "requested data journaling mode");
2855 clear_opt(sbi->s_mount_opt, DELALLOC); 2877 clear_opt(sbi->s_mount_opt, DELALLOC);
2856 } else if (test_opt(sb, DELALLOC)) 2878 }
2857 ext4_msg(sb, KERN_INFO, "delayed allocation enabled");
2858 2879
2859 err = ext4_setup_system_zone(sb); 2880 err = ext4_setup_system_zone(sb);
2860 if (err) { 2881 if (err) {
@@ -2910,6 +2931,8 @@ cantfind_ext4:
2910 2931
2911failed_mount4: 2932failed_mount4:
2912 ext4_msg(sb, KERN_ERR, "mount failed"); 2933 ext4_msg(sb, KERN_ERR, "mount failed");
2934 destroy_workqueue(EXT4_SB(sb)->dio_unwritten_wq);
2935failed_mount_wq:
2913 ext4_release_system_zone(sb); 2936 ext4_release_system_zone(sb);
2914 if (sbi->s_journal) { 2937 if (sbi->s_journal) {
2915 jbd2_journal_destroy(sbi->s_journal); 2938 jbd2_journal_destroy(sbi->s_journal);
@@ -3164,9 +3187,7 @@ static int ext4_load_journal(struct super_block *sb,
3164 return -EINVAL; 3187 return -EINVAL;
3165 } 3188 }
3166 3189
3167 if (journal->j_flags & JBD2_BARRIER) 3190 if (!(journal->j_flags & JBD2_BARRIER))
3168 ext4_msg(sb, KERN_INFO, "barriers enabled");
3169 else
3170 ext4_msg(sb, KERN_INFO, "barriers disabled"); 3191 ext4_msg(sb, KERN_INFO, "barriers disabled");
3171 3192
3172 if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { 3193 if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
@@ -3361,11 +3382,13 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
3361{ 3382{
3362 int ret = 0; 3383 int ret = 0;
3363 tid_t target; 3384 tid_t target;
3385 struct ext4_sb_info *sbi = EXT4_SB(sb);
3364 3386
3365 trace_ext4_sync_fs(sb, wait); 3387 trace_ext4_sync_fs(sb, wait);
3366 if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { 3388 flush_workqueue(sbi->dio_unwritten_wq);
3389 if (jbd2_journal_start_commit(sbi->s_journal, &target)) {
3367 if (wait) 3390 if (wait)
3368 jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); 3391 jbd2_log_wait_commit(sbi->s_journal, target);
3369 } 3392 }
3370 return ret; 3393 return ret;
3371} 3394}
@@ -3951,27 +3974,6 @@ static struct file_system_type ext4_fs_type = {
3951 .fs_flags = FS_REQUIRES_DEV, 3974 .fs_flags = FS_REQUIRES_DEV,
3952}; 3975};
3953 3976
3954#ifdef CONFIG_EXT4DEV_COMPAT
3955static int ext4dev_get_sb(struct file_system_type *fs_type, int flags,
3956 const char *dev_name, void *data,struct vfsmount *mnt)
3957{
3958 printk(KERN_WARNING "EXT4-fs (%s): Update your userspace programs "
3959 "to mount using ext4\n", dev_name);
3960 printk(KERN_WARNING "EXT4-fs (%s): ext4dev backwards compatibility "
3961 "will go away by 2.6.31\n", dev_name);
3962 return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
3963}
3964
3965static struct file_system_type ext4dev_fs_type = {
3966 .owner = THIS_MODULE,
3967 .name = "ext4dev",
3968 .get_sb = ext4dev_get_sb,
3969 .kill_sb = kill_block_super,
3970 .fs_flags = FS_REQUIRES_DEV,
3971};
3972MODULE_ALIAS("ext4dev");
3973#endif
3974
3975static int __init init_ext4_fs(void) 3977static int __init init_ext4_fs(void)
3976{ 3978{
3977 int err; 3979 int err;
@@ -3996,13 +3998,6 @@ static int __init init_ext4_fs(void)
3996 err = register_filesystem(&ext4_fs_type); 3998 err = register_filesystem(&ext4_fs_type);
3997 if (err) 3999 if (err)
3998 goto out; 4000 goto out;
3999#ifdef CONFIG_EXT4DEV_COMPAT
4000 err = register_filesystem(&ext4dev_fs_type);
4001 if (err) {
4002 unregister_filesystem(&ext4_fs_type);
4003 goto out;
4004 }
4005#endif
4006 return 0; 4001 return 0;
4007out: 4002out:
4008 destroy_inodecache(); 4003 destroy_inodecache();
@@ -4021,9 +4016,6 @@ out4:
4021static void __exit exit_ext4_fs(void) 4016static void __exit exit_ext4_fs(void)
4022{ 4017{
4023 unregister_filesystem(&ext4_fs_type); 4018 unregister_filesystem(&ext4_fs_type);
4024#ifdef CONFIG_EXT4DEV_COMPAT
4025 unregister_filesystem(&ext4dev_fs_type);
4026#endif
4027 destroy_inodecache(); 4019 destroy_inodecache();
4028 exit_ext4_xattr(); 4020 exit_ext4_xattr();
4029 exit_ext4_mballoc(); 4021 exit_ext4_mballoc();