Sync up latest jmap patches
[ext4-patch-queue.git] / add-journal-no-cleanup-option
blob11de50f33aa245b367ca965e01b07d7225463609
1 ext4, jbd2: add the journal_nocleanup mount option
3 This debugging option is useful for generating test cases for the
4 journal replay code.
6 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
7 ---
8  fs/ext4/ext4.h       |  1 +
9  fs/ext4/super.c      |  9 +++++++++
10  fs/jbd2/journal.c    | 12 +++++++++---
11  include/linux/jbd2.h |  1 +
12  4 files changed, 20 insertions(+), 3 deletions(-)
14 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
15 index 55b7a77a0444..63a4be5d5b17 100644
16 --- a/fs/ext4/ext4.h
17 +++ b/fs/ext4/ext4.h
18 @@ -1144,6 +1144,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_NO_CLEANUP  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 dde14a7ac6d7..233fccf28025 100644
28 --- a/fs/ext4/super.c
29 +++ b/fs/ext4/super.c
30 @@ -1308,6 +1308,7 @@ enum {
31         Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
32         Opt_inode_readahead_blks, Opt_journal_ioprio,
33         Opt_dioread_nolock, Opt_dioread_lock,
34 +       Opt_journal_nocleanup, Opt_journal_cleanup,
35         Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
36         Opt_max_dir_size_kb, Opt_nojournal_checksum,
37  };
38 @@ -1392,6 +1393,8 @@ static const match_table_t tokens = {
39         {Opt_noinit_itable, "noinit_itable"},
40         {Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
41         {Opt_test_dummy_encryption, "test_dummy_encryption"},
42 +       {Opt_journal_nocleanup, "journal_nocleanup"},
43 +       {Opt_journal_cleanup, "journal_cleanup"},
44         {Opt_removed, "check=none"},    /* mount option from ext2/3 */
45         {Opt_removed, "nocheck"},       /* mount option from ext2/3 */
46         {Opt_removed, "reservation"},   /* mount option from ext2/3 */
47 @@ -1598,6 +1601,8 @@ static const struct mount_opts {
48         {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
49         {Opt_max_dir_size_kb, 0, MOPT_GTE0},
50         {Opt_test_dummy_encryption, 0, MOPT_GTE0},
51 +       {Opt_journal_nocleanup, EXT4_MOUNT_JOURNAL_NO_CLEANUP, MOPT_SET},
52 +       {Opt_journal_cleanup, EXT4_MOUNT_JOURNAL_NO_CLEANUP, MOPT_CLEAR},
53         {Opt_err, 0, 0}
54  };
56 @@ -4328,6 +4333,10 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
57                 journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR;
58         else
59                 journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR;
60 +       if (test_opt(sb, JOURNAL_NO_CLEANUP))
61 +               journal->j_flags |= JBD2_NO_CLEANUP;
62 +       else
63 +               journal->j_flags &= ~JBD2_NO_CLEANUP;
64         write_unlock(&journal->j_state_lock);
65  }
67 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
68 index 85d1483939b2..f7fd801be997 100644
69 --- a/fs/jbd2/journal.c
70 +++ b/fs/jbd2/journal.c
71 @@ -1685,6 +1685,11 @@ int jbd2_journal_destroy(journal_t *journal)
72         if (journal->j_running_transaction)
73                 jbd2_journal_commit_transaction(journal);
75 +       if (journal->j_flags & JBD2_NO_CLEANUP) {
76 +               jbd2_journal_destroy_checkpoint(journal);
77 +               journal->j_checkpoint_transactions = NULL;
78 +       }
80         /* Force any old transactions to disk */
82         /* Totally anal locking here... */
83 @@ -1712,7 +1717,9 @@ int jbd2_journal_destroy(journal_t *journal)
84         spin_unlock(&journal->j_list_lock);
86         if (journal->j_sb_buffer) {
87 -               if (!is_journal_aborted(journal)) {
88 +               if (is_journal_aborted(journal))
89 +                       err = -EIO;
90 +               else if ((journal->j_flags & JBD2_NO_CLEANUP) == 0) {
91                         mutex_lock(&journal->j_checkpoint_mutex);
93                         write_lock(&journal->j_state_lock);
94 @@ -1723,8 +1730,7 @@ int jbd2_journal_destroy(journal_t *journal)
95                         jbd2_mark_journal_empty(journal,
96                                         REQ_PREFLUSH | REQ_FUA);
97                         mutex_unlock(&journal->j_checkpoint_mutex);
98 -               } else
99 -                       err = -EIO;
100 +               }
101                 brelse(journal->j_sb_buffer);
102         }
104 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
105 index dfaa1f4dcb0c..9a07b0485784 100644
106 --- a/include/linux/jbd2.h
107 +++ b/include/linux/jbd2.h
108 @@ -1128,6 +1128,7 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3,                CSUM_V3)
109                                                  * data write error in ordered
110                                                  * mode */
111  #define JBD2_REC_ERR   0x080   /* The errno in the sb has been recorded */
112 +#define JBD2_NO_CLEANUP        0x100   /* Don't flush empty the journal on shutdown  */
114  /*
115   * Function declarations for the journaling transaction and buffer