aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorFrank Mayhar <fmayhar@google.com>2009-01-07 00:06:22 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-07 00:06:22 -0500
commit0390131ba84fd3f726f9e24fc4553828125700bb (patch)
tree4c90afad4e8690e25aec0ce069fd450e92ab5f96 /fs/ext4/super.c
parentff7ef329b268b603ea4a2303241ef1c3829fd574 (diff)
ext4: Allow ext4 to run without a journal
A few weeks ago I posted a patch for discussion that allowed ext4 to run without a journal. Since that time I've integrated the excellent comments from Andreas and fixed several serious bugs. We're currently running with this patch and generating some performance numbers against both ext2 (with backported reservations code) and ext4 with and without a journal. It just so happens that running without a journal is slightly faster for most everything. We did iozone -T -t 4 s 2g -r 256k -T -I -i0 -i1 -i2 which creates 4 threads, each of which create and do reads and writes on a 2G file, with a buffer size of 256K, using O_DIRECT for all file opens to bypass the page cache. Results: ext2 ext4, default ext4, no journal initial writes 13.0 MB/s 15.4 MB/s 15.7 MB/s rewrites 13.1 MB/s 15.6 MB/s 15.9 MB/s reads 15.2 MB/s 16.9 MB/s 17.2 MB/s re-reads 15.3 MB/s 16.9 MB/s 17.2 MB/s random readers 5.6 MB/s 5.6 MB/s 5.7 MB/s random writers 5.1 MB/s 5.3 MB/s 5.4 MB/s So it seems that, so far, this was a useful exercise. Signed-off-by: Frank Mayhar <fmayhar@google.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c207
1 files changed, 140 insertions, 67 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8a0ae883f567..9b9076d9c4f7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -136,13 +136,19 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
136 * backs (eg. EIO in the commit thread), then we still need to 136 * backs (eg. EIO in the commit thread), then we still need to
137 * take the FS itself readonly cleanly. */ 137 * take the FS itself readonly cleanly. */
138 journal = EXT4_SB(sb)->s_journal; 138 journal = EXT4_SB(sb)->s_journal;
139 if (is_journal_aborted(journal)) { 139 if (journal) {
140 ext4_abort(sb, __func__, 140 if (is_journal_aborted(journal)) {
141 "Detected aborted journal"); 141 ext4_abort(sb, __func__,
142 return ERR_PTR(-EROFS); 142 "Detected aborted journal");
143 return ERR_PTR(-EROFS);
144 }
145 return jbd2_journal_start(journal, nblocks);
143 } 146 }
144 147 /*
145 return jbd2_journal_start(journal, nblocks); 148 * We're not journaling, return the appropriate indication.
149 */
150 current->journal_info = EXT4_NOJOURNAL_HANDLE;
151 return current->journal_info;
146} 152}
147 153
148/* 154/*
@@ -157,6 +163,14 @@ int __ext4_journal_stop(const char *where, handle_t *handle)
157 int err; 163 int err;
158 int rc; 164 int rc;
159 165
166 if (!ext4_handle_valid(handle)) {
167 /*
168 * Do this here since we don't call jbd2_journal_stop() in
169 * no-journal mode.
170 */
171 current->journal_info = NULL;
172 return 0;
173 }
160 sb = handle->h_transaction->t_journal->j_private; 174 sb = handle->h_transaction->t_journal->j_private;
161 err = handle->h_err; 175 err = handle->h_err;
162 rc = jbd2_journal_stop(handle); 176 rc = jbd2_journal_stop(handle);
@@ -174,6 +188,8 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn,
174 char nbuf[16]; 188 char nbuf[16];
175 const char *errstr = ext4_decode_error(NULL, err, nbuf); 189 const char *errstr = ext4_decode_error(NULL, err, nbuf);
176 190
191 BUG_ON(!ext4_handle_valid(handle));
192
177 if (bh) 193 if (bh)
178 BUFFER_TRACE(bh, "abort"); 194 BUFFER_TRACE(bh, "abort");
179 195
@@ -448,11 +464,13 @@ static void ext4_put_super(struct super_block *sb)
448 ext4_mb_release(sb); 464 ext4_mb_release(sb);
449 ext4_ext_release(sb); 465 ext4_ext_release(sb);
450 ext4_xattr_put_super(sb); 466 ext4_xattr_put_super(sb);
451 err = jbd2_journal_destroy(sbi->s_journal); 467 if (sbi->s_journal) {
452 sbi->s_journal = NULL; 468 err = jbd2_journal_destroy(sbi->s_journal);
453 if (err < 0) 469 sbi->s_journal = NULL;
454 ext4_abort(sb, __func__, "Couldn't clean up the journal"); 470 if (err < 0)
455 471 ext4_abort(sb, __func__,
472 "Couldn't clean up the journal");
473 }
456 if (!(sb->s_flags & MS_RDONLY)) { 474 if (!(sb->s_flags & MS_RDONLY)) {
457 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 475 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
458 es->s_state = cpu_to_le16(sbi->s_mount_state); 476 es->s_state = cpu_to_le16(sbi->s_mount_state);
@@ -522,6 +540,11 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
522 memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); 540 memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
523 INIT_LIST_HEAD(&ei->i_prealloc_list); 541 INIT_LIST_HEAD(&ei->i_prealloc_list);
524 spin_lock_init(&ei->i_prealloc_lock); 542 spin_lock_init(&ei->i_prealloc_lock);
543 /*
544 * Note: We can be called before EXT4_SB(sb)->s_journal is set,
545 * therefore it can be null here. Don't check it, just initialize
546 * jinode.
547 */
525 jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode); 548 jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode);
526 ei->i_reserved_data_blocks = 0; 549 ei->i_reserved_data_blocks = 0;
527 ei->i_reserved_meta_blocks = 0; 550 ei->i_reserved_meta_blocks = 0;
@@ -588,7 +611,8 @@ static void ext4_clear_inode(struct inode *inode)
588 } 611 }
589#endif 612#endif
590 ext4_discard_preallocations(inode); 613 ext4_discard_preallocations(inode);
591 jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, 614 if (EXT4_JOURNAL(inode))
615 jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,
592 &EXT4_I(inode)->jinode); 616 &EXT4_I(inode)->jinode);
593} 617}
594 618
@@ -1406,20 +1430,15 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1406 printk(KERN_WARNING 1430 printk(KERN_WARNING
1407 "EXT4-fs warning: checktime reached, " 1431 "EXT4-fs warning: checktime reached, "
1408 "running e2fsck is recommended\n"); 1432 "running e2fsck is recommended\n");
1409#if 0 1433 if (!sbi->s_journal)
1410 /* @@@ We _will_ want to clear the valid bit if we find 1434 es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
1411 * inconsistencies, to force a fsck at reboot. But for
1412 * a plain journaled filesystem we can keep it set as
1413 * valid forever! :)
1414 */
1415 es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
1416#endif
1417 if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) 1435 if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
1418 es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT); 1436 es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT);
1419 le16_add_cpu(&es->s_mnt_count, 1); 1437 le16_add_cpu(&es->s_mnt_count, 1);
1420 es->s_mtime = cpu_to_le32(get_seconds()); 1438 es->s_mtime = cpu_to_le32(get_seconds());
1421 ext4_update_dynamic_rev(sb); 1439 ext4_update_dynamic_rev(sb);
1422 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 1440 if (sbi->s_journal)
1441 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
1423 1442
1424 ext4_commit_super(sb, es, 1); 1443 ext4_commit_super(sb, es, 1);
1425 if (test_opt(sb, DEBUG)) 1444 if (test_opt(sb, DEBUG))
@@ -1431,9 +1450,13 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1431 EXT4_INODES_PER_GROUP(sb), 1450 EXT4_INODES_PER_GROUP(sb),
1432 sbi->s_mount_opt); 1451 sbi->s_mount_opt);
1433 1452
1434 printk(KERN_INFO "EXT4 FS on %s, %s journal on %s\n", 1453 if (EXT4_SB(sb)->s_journal) {
1435 sb->s_id, EXT4_SB(sb)->s_journal->j_inode ? "internal" : 1454 printk(KERN_INFO "EXT4 FS on %s, %s journal on %s\n",
1436 "external", EXT4_SB(sb)->s_journal->j_devname); 1455 sb->s_id, EXT4_SB(sb)->s_journal->j_inode ? "internal" :
1456 "external", EXT4_SB(sb)->s_journal->j_devname);
1457 } else {
1458 printk(KERN_INFO "EXT4 FS on %s, no journal\n", sb->s_id);
1459 }
1437 return res; 1460 return res;
1438} 1461}
1439 1462
@@ -1867,6 +1890,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
1867 unsigned long def_mount_opts; 1890 unsigned long def_mount_opts;
1868 struct inode *root; 1891 struct inode *root;
1869 char *cp; 1892 char *cp;
1893 const char *descr;
1870 int ret = -EINVAL; 1894 int ret = -EINVAL;
1871 int blocksize; 1895 int blocksize;
1872 int db_count; 1896 int db_count;
@@ -2278,21 +2302,23 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2278 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 2302 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
2279 es->s_state |= cpu_to_le16(EXT4_ERROR_FS); 2303 es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
2280 ext4_commit_super(sb, es, 1); 2304 ext4_commit_super(sb, es, 1);
2281 printk(KERN_CRIT
2282 "EXT4-fs (device %s): mount failed\n",
2283 sb->s_id);
2284 goto failed_mount4; 2305 goto failed_mount4;
2285 } 2306 }
2286 } 2307 }
2287 } else if (journal_inum) { 2308 } else if (journal_inum) {
2288 if (ext4_create_journal(sb, es, journal_inum)) 2309 if (ext4_create_journal(sb, es, journal_inum))
2289 goto failed_mount3; 2310 goto failed_mount3;
2311 } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
2312 EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
2313 printk(KERN_ERR "EXT4-fs: required journal recovery "
2314 "suppressed and not mounted read-only\n");
2315 goto failed_mount4;
2290 } else { 2316 } else {
2291 if (!silent) 2317 clear_opt(sbi->s_mount_opt, DATA_FLAGS);
2292 printk(KERN_ERR 2318 set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
2293 "ext4: No journal on filesystem on %s\n", 2319 sbi->s_journal = NULL;
2294 sb->s_id); 2320 needs_recovery = 0;
2295 goto failed_mount3; 2321 goto no_journal;
2296 } 2322 }
2297 2323
2298 if (ext4_blocks_count(es) > 0xffffffffULL && 2324 if (ext4_blocks_count(es) > 0xffffffffULL &&
@@ -2344,6 +2370,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2344 break; 2370 break;
2345 } 2371 }
2346 2372
2373no_journal:
2374
2347 if (test_opt(sb, NOBH)) { 2375 if (test_opt(sb, NOBH)) {
2348 if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { 2376 if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {
2349 printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - " 2377 printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - "
@@ -2428,13 +2456,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2428 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; 2456 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
2429 ext4_orphan_cleanup(sb, es); 2457 ext4_orphan_cleanup(sb, es);
2430 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; 2458 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
2431 if (needs_recovery) 2459 if (needs_recovery) {
2432 printk(KERN_INFO "EXT4-fs: recovery complete.\n"); 2460 printk(KERN_INFO "EXT4-fs: recovery complete.\n");
2433 ext4_mark_recovery_complete(sb, es); 2461 ext4_mark_recovery_complete(sb, es);
2434 printk(KERN_INFO "EXT4-fs: mounted filesystem with %s data mode.\n", 2462 }
2435 test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ? "journal": 2463 if (EXT4_SB(sb)->s_journal) {
2436 test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": 2464 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
2437 "writeback"); 2465 descr = " journalled data mode";
2466 else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
2467 descr = " ordered data mode";
2468 else
2469 descr = " writeback data mode";
2470 } else
2471 descr = "out journal";
2472
2473 printk(KERN_INFO "EXT4-fs: mounted filesystem %s with%s\n",
2474 sb->s_id, descr);
2438 2475
2439 lock_kernel(); 2476 lock_kernel();
2440 return 0; 2477 return 0;
@@ -2446,8 +2483,11 @@ cantfind_ext4:
2446 goto failed_mount; 2483 goto failed_mount;
2447 2484
2448failed_mount4: 2485failed_mount4:
2449 jbd2_journal_destroy(sbi->s_journal); 2486 printk(KERN_ERR "EXT4-fs (device %s): mount failed\n", sb->s_id);
2450 sbi->s_journal = NULL; 2487 if (sbi->s_journal) {
2488 jbd2_journal_destroy(sbi->s_journal);
2489 sbi->s_journal = NULL;
2490 }
2451failed_mount3: 2491failed_mount3:
2452 percpu_counter_destroy(&sbi->s_freeblocks_counter); 2492 percpu_counter_destroy(&sbi->s_freeblocks_counter);
2453 percpu_counter_destroy(&sbi->s_freeinodes_counter); 2493 percpu_counter_destroy(&sbi->s_freeinodes_counter);
@@ -2508,6 +2548,8 @@ static journal_t *ext4_get_journal(struct super_block *sb,
2508 struct inode *journal_inode; 2548 struct inode *journal_inode;
2509 journal_t *journal; 2549 journal_t *journal;
2510 2550
2551 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2552
2511 /* First, test for the existence of a valid inode on disk. Bad 2553 /* First, test for the existence of a valid inode on disk. Bad
2512 * things happen if we iget() an unused inode, as the subsequent 2554 * things happen if we iget() an unused inode, as the subsequent
2513 * iput() will try to delete it. */ 2555 * iput() will try to delete it. */
@@ -2556,6 +2598,8 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
2556 struct ext4_super_block *es; 2598 struct ext4_super_block *es;
2557 struct block_device *bdev; 2599 struct block_device *bdev;
2558 2600
2601 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2602
2559 bdev = ext4_blkdev_get(j_dev); 2603 bdev = ext4_blkdev_get(j_dev);
2560 if (bdev == NULL) 2604 if (bdev == NULL)
2561 return NULL; 2605 return NULL;
@@ -2643,6 +2687,8 @@ static int ext4_load_journal(struct super_block *sb,
2643 int err = 0; 2687 int err = 0;
2644 int really_read_only; 2688 int really_read_only;
2645 2689
2690 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2691
2646 if (journal_devnum && 2692 if (journal_devnum &&
2647 journal_devnum != le32_to_cpu(es->s_journal_dev)) { 2693 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
2648 printk(KERN_INFO "EXT4-fs: external journal device major/minor " 2694 printk(KERN_INFO "EXT4-fs: external journal device major/minor "
@@ -2817,6 +2863,10 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
2817{ 2863{
2818 journal_t *journal = EXT4_SB(sb)->s_journal; 2864 journal_t *journal = EXT4_SB(sb)->s_journal;
2819 2865
2866 if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
2867 BUG_ON(journal != NULL);
2868 return;
2869 }
2820 jbd2_journal_lock_updates(journal); 2870 jbd2_journal_lock_updates(journal);
2821 if (jbd2_journal_flush(journal) < 0) 2871 if (jbd2_journal_flush(journal) < 0)
2822 goto out; 2872 goto out;
@@ -2846,6 +2896,8 @@ static void ext4_clear_journal_err(struct super_block *sb,
2846 int j_errno; 2896 int j_errno;
2847 const char *errstr; 2897 const char *errstr;
2848 2898
2899 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2900
2849 journal = EXT4_SB(sb)->s_journal; 2901 journal = EXT4_SB(sb)->s_journal;
2850 2902
2851 /* 2903 /*
@@ -2878,14 +2930,17 @@ static void ext4_clear_journal_err(struct super_block *sb,
2878int ext4_force_commit(struct super_block *sb) 2930int ext4_force_commit(struct super_block *sb)
2879{ 2931{
2880 journal_t *journal; 2932 journal_t *journal;
2881 int ret; 2933 int ret = 0;
2882 2934
2883 if (sb->s_flags & MS_RDONLY) 2935 if (sb->s_flags & MS_RDONLY)
2884 return 0; 2936 return 0;
2885 2937
2886 journal = EXT4_SB(sb)->s_journal; 2938 journal = EXT4_SB(sb)->s_journal;
2887 sb->s_dirt = 0; 2939 if (journal) {
2888 ret = ext4_journal_force_commit(journal); 2940 sb->s_dirt = 0;
2941 ret = ext4_journal_force_commit(journal);
2942 }
2943
2889 return ret; 2944 return ret;
2890} 2945}
2891 2946
@@ -2897,9 +2952,13 @@ int ext4_force_commit(struct super_block *sb)
2897 */ 2952 */
2898static void ext4_write_super(struct super_block *sb) 2953static void ext4_write_super(struct super_block *sb)
2899{ 2954{
2900 if (mutex_trylock(&sb->s_lock) != 0) 2955 if (EXT4_SB(sb)->s_journal) {
2901 BUG(); 2956 if (mutex_trylock(&sb->s_lock) != 0)
2902 sb->s_dirt = 0; 2957 BUG();
2958 sb->s_dirt = 0;
2959 } else {
2960 ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
2961 }
2903} 2962}
2904 2963
2905static int ext4_sync_fs(struct super_block *sb, int wait) 2964static int ext4_sync_fs(struct super_block *sb, int wait)
@@ -2908,10 +2967,14 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
2908 2967
2909 trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); 2968 trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
2910 sb->s_dirt = 0; 2969 sb->s_dirt = 0;
2911 if (wait) 2970 if (EXT4_SB(sb)->s_journal) {
2912 ret = ext4_force_commit(sb); 2971 if (wait)
2913 else 2972 ret = ext4_force_commit(sb);
2914 jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); 2973 else
2974 jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL);
2975 } else {
2976 ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait);
2977 }
2915 return ret; 2978 return ret;
2916} 2979}
2917 2980
@@ -2926,15 +2989,17 @@ static void ext4_write_super_lockfs(struct super_block *sb)
2926 if (!(sb->s_flags & MS_RDONLY)) { 2989 if (!(sb->s_flags & MS_RDONLY)) {
2927 journal_t *journal = EXT4_SB(sb)->s_journal; 2990 journal_t *journal = EXT4_SB(sb)->s_journal;
2928 2991
2929 /* Now we set up the journal barrier. */ 2992 if (journal) {
2930 jbd2_journal_lock_updates(journal); 2993 /* Now we set up the journal barrier. */
2994 jbd2_journal_lock_updates(journal);
2931 2995
2932 /* 2996 /*
2933 * We don't want to clear needs_recovery flag when we failed 2997 * We don't want to clear needs_recovery flag when we
2934 * to flush the journal. 2998 * failed to flush the journal.
2935 */ 2999 */
2936 if (jbd2_journal_flush(journal) < 0) 3000 if (jbd2_journal_flush(journal) < 0)
2937 return; 3001 return;
3002 }
2938 3003
2939 /* Journal blocked and flushed, clear needs_recovery flag. */ 3004 /* Journal blocked and flushed, clear needs_recovery flag. */
2940 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3005 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
@@ -2948,7 +3013,7 @@ static void ext4_write_super_lockfs(struct super_block *sb)
2948 */ 3013 */
2949static void ext4_unlockfs(struct super_block *sb) 3014static void ext4_unlockfs(struct super_block *sb)
2950{ 3015{
2951 if (!(sb->s_flags & MS_RDONLY)) { 3016 if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
2952 lock_super(sb); 3017 lock_super(sb);
2953 /* Reser the needs_recovery flag before the fs is unlocked. */ 3018 /* Reser the needs_recovery flag before the fs is unlocked. */
2954 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3019 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
@@ -2999,7 +3064,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
2999 3064
3000 es = sbi->s_es; 3065 es = sbi->s_es;
3001 3066
3002 ext4_init_journal_params(sb, sbi->s_journal); 3067 if (sbi->s_journal)
3068 ext4_init_journal_params(sb, sbi->s_journal);
3003 3069
3004 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || 3070 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
3005 n_blocks_count > ext4_blocks_count(es)) { 3071 n_blocks_count > ext4_blocks_count(es)) {
@@ -3028,9 +3094,11 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3028 * We have to unlock super so that we can wait for 3094 * We have to unlock super so that we can wait for
3029 * transactions. 3095 * transactions.
3030 */ 3096 */
3031 unlock_super(sb); 3097 if (sbi->s_journal) {
3032 ext4_mark_recovery_complete(sb, es); 3098 unlock_super(sb);
3033 lock_super(sb); 3099 ext4_mark_recovery_complete(sb, es);
3100 lock_super(sb);
3101 }
3034 } else { 3102 } else {
3035 __le32 ret; 3103 __le32 ret;
3036 if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, 3104 if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb,
@@ -3084,7 +3152,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3084 * been changed by e2fsck since we originally mounted 3152 * been changed by e2fsck since we originally mounted
3085 * the partition.) 3153 * the partition.)
3086 */ 3154 */
3087 ext4_clear_journal_err(sb, es); 3155 if (sbi->s_journal)
3156 ext4_clear_journal_err(sb, es);
3088 sbi->s_mount_state = le16_to_cpu(es->s_state); 3157 sbi->s_mount_state = le16_to_cpu(es->s_state);
3089 if ((err = ext4_group_extend(sb, es, n_blocks_count))) 3158 if ((err = ext4_group_extend(sb, es, n_blocks_count)))
3090 goto restore_opts; 3159 goto restore_opts;
@@ -3092,6 +3161,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3092 sb->s_flags &= ~MS_RDONLY; 3161 sb->s_flags &= ~MS_RDONLY;
3093 } 3162 }
3094 } 3163 }
3164 if (sbi->s_journal == NULL)
3165 ext4_commit_super(sb, es, 1);
3166
3095#ifdef CONFIG_QUOTA 3167#ifdef CONFIG_QUOTA
3096 /* Release old quota file names */ 3168 /* Release old quota file names */
3097 for (i = 0; i < MAXQUOTAS; i++) 3169 for (i = 0; i < MAXQUOTAS; i++)
@@ -3368,7 +3440,8 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
3368 * When we journal data on quota file, we have to flush journal to see 3440 * When we journal data on quota file, we have to flush journal to see
3369 * all updates to the file when we bypass pagecache... 3441 * all updates to the file when we bypass pagecache...
3370 */ 3442 */
3371 if (ext4_should_journal_data(path.dentry->d_inode)) { 3443 if (EXT4_SB(sb)->s_journal &&
3444 ext4_should_journal_data(path.dentry->d_inode)) {
3372 /* 3445 /*
3373 * We don't need to lock updates but journal_flush() could 3446 * We don't need to lock updates but journal_flush() could
3374 * otherwise be livelocked... 3447 * otherwise be livelocked...
@@ -3442,7 +3515,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
3442 struct buffer_head *bh; 3515 struct buffer_head *bh;
3443 handle_t *handle = journal_current_handle(); 3516 handle_t *handle = journal_current_handle();
3444 3517
3445 if (!handle) { 3518 if (EXT4_SB(sb)->s_journal && !handle) {
3446 printk(KERN_WARNING "EXT4-fs: Quota write (off=%llu, len=%llu)" 3519 printk(KERN_WARNING "EXT4-fs: Quota write (off=%llu, len=%llu)"
3447 " cancelled because transaction is not started.\n", 3520 " cancelled because transaction is not started.\n",
3448 (unsigned long long)off, (unsigned long long)len); 3521 (unsigned long long)off, (unsigned long long)len);
@@ -3467,7 +3540,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
3467 flush_dcache_page(bh->b_page); 3540 flush_dcache_page(bh->b_page);
3468 unlock_buffer(bh); 3541 unlock_buffer(bh);
3469 if (journal_quota) 3542 if (journal_quota)
3470 err = ext4_journal_dirty_metadata(handle, bh); 3543 err = ext4_handle_dirty_metadata(handle, NULL, bh);
3471 else { 3544 else {
3472 /* Always do at least ordered writes for quotas */ 3545 /* Always do at least ordered writes for quotas */
3473 err = ext4_jbd2_file_inode(handle, inode); 3546 err = ext4_jbd2_file_inode(handle, inode);