diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 207 |
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 | ||
2373 | no_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 | ||
2448 | failed_mount4: | 2485 | failed_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 | } | ||
2451 | failed_mount3: | 2491 | failed_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, | |||
2878 | int ext4_force_commit(struct super_block *sb) | 2930 | int 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 | */ |
2898 | static void ext4_write_super(struct super_block *sb) | 2953 | static 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 | ||
2905 | static int ext4_sync_fs(struct super_block *sb, int wait) | 2964 | static 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 | */ |
2949 | static void ext4_unlockfs(struct super_block *sb) | 3014 | static 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); |