1 ext4, jbd2: add the journal_nocleanup mount option
3 This debugging option is useful for generating test cases for the
6 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
9 fs/ext4/super.c | 11 ++++++++++-
10 fs/jbd2/journal.c | 12 +++++++++---
11 include/linux/jbd2.h | 1 +
12 4 files changed, 21 insertions(+), 4 deletions(-)
14 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
15 index 4e091eae38b1..d1389c9fb8a1 100644
18 @@ -1108,6 +1108,7 @@ struct ext4_inode_info {
19 #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */
20 #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
21 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
22 +#define EXT4_MOUNT_JOURNAL_NOCLEANUP 0x2000000 /* Preserve the journal on unmount */
23 #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
24 #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
25 #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
26 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
27 index 6783af7ec115..06da44b3d8e1 100644
30 @@ -888,7 +888,7 @@ static void ext4_put_super(struct super_block *sb)
34 - if (!sb_rdonly(sb) && !aborted) {
35 + if (!sb_rdonly(sb) && !aborted && !test_opt(sb, JOURNAL_NOCLEANUP)) {
36 ext4_clear_feature_journal_needs_recovery(sb);
37 es->s_state = cpu_to_le16(sbi->s_mount_state);
39 @@ -1348,6 +1348,7 @@ enum {
40 Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
41 Opt_inode_readahead_blks, Opt_journal_ioprio,
42 Opt_dioread_nolock, Opt_dioread_lock,
43 + Opt_journal_nocleanup, Opt_journal_cleanup,
44 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
45 Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache,
47 @@ -1434,6 +1435,8 @@ static const match_table_t tokens = {
48 {Opt_test_dummy_encryption, "test_dummy_encryption"},
49 {Opt_nombcache, "nombcache"},
50 {Opt_nombcache, "no_mbcache"}, /* for backward compatibility */
51 + {Opt_journal_nocleanup, "journal_nocleanup"},
52 + {Opt_journal_cleanup, "journal_cleanup"},
53 {Opt_removed, "check=none"}, /* mount option from ext2/3 */
54 {Opt_removed, "nocheck"}, /* mount option from ext2/3 */
55 {Opt_removed, "reservation"}, /* mount option from ext2/3 */
56 @@ -1642,6 +1645,8 @@ static const struct mount_opts {
57 {Opt_max_dir_size_kb, 0, MOPT_GTE0},
58 {Opt_test_dummy_encryption, 0, MOPT_GTE0},
59 {Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
60 + {Opt_journal_nocleanup, EXT4_MOUNT_JOURNAL_NOCLEANUP, MOPT_SET},
61 + {Opt_journal_cleanup, EXT4_MOUNT_JOURNAL_NOCLEANUP, MOPT_CLEAR},
65 @@ -4447,6 +4452,10 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
66 journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR;
68 journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR;
69 + if (test_opt(sb, JOURNAL_NOCLEANUP))
70 + journal->j_flags |= JBD2_NO_CLEANUP;
72 + journal->j_flags &= ~JBD2_NO_CLEANUP;
73 write_unlock(&journal->j_state_lock);
76 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
77 index b01f07f65d59..218c50dd9dfc 100644
78 --- a/fs/jbd2/journal.c
79 +++ b/fs/jbd2/journal.c
80 @@ -1724,6 +1724,11 @@ int jbd2_journal_destroy(journal_t *journal)
81 if (journal->j_running_transaction)
82 jbd2_journal_commit_transaction(journal);
84 + if (journal->j_flags & JBD2_NO_CLEANUP) {
85 + jbd2_journal_destroy_checkpoint(journal);
86 + journal->j_checkpoint_transactions = NULL;
89 /* Force any old transactions to disk */
91 /* Totally anal locking here... */
92 @@ -1751,7 +1756,9 @@ int jbd2_journal_destroy(journal_t *journal)
93 spin_unlock(&journal->j_list_lock);
95 if (journal->j_sb_buffer) {
96 - if (!is_journal_aborted(journal)) {
97 + if (is_journal_aborted(journal))
99 + else if ((journal->j_flags & JBD2_NO_CLEANUP) == 0) {
100 mutex_lock_io(&journal->j_checkpoint_mutex);
102 write_lock(&journal->j_state_lock);
103 @@ -1762,8 +1769,7 @@ int jbd2_journal_destroy(journal_t *journal)
104 jbd2_mark_journal_empty(journal,
105 REQ_SYNC | REQ_PREFLUSH | REQ_FUA);
106 mutex_unlock(&journal->j_checkpoint_mutex);
110 brelse(journal->j_sb_buffer);
113 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
114 index 296d1e0ea87b..58ec2b764abd 100644
115 --- a/include/linux/jbd2.h
116 +++ b/include/linux/jbd2.h
117 @@ -1130,6 +1130,7 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3)
118 * data write error in ordered
120 #define JBD2_REC_ERR 0x080 /* The errno in the sb has been recorded */
121 +#define JBD2_NO_CLEANUP 0x100 /* Don't flush empty the journal on shutdown */
124 * Function declarations for the journaling transaction and buffer