1 Do not trim journal. Always recover the tail.
3 From: Abutalib Aghayev <agayev@gmail.com>
5 With this commit, after the first write to the journal, journal always
6 starts at block 1 and transaction 2. During mount, we recover and
7 replay all the entries in the journal and we find out the actual tail.
8 Newer transactions are written at this new tail. This is done in
9 preparation for stopping metadata block writeback.
11 The change to commit.c prevents the journal superblock from being
12 updated. The change to super.c prevents wiping of the journal upon
13 mount after a clean unmount. The change to jbd2_mark_journal_empty
14 always sets the journal start from the beginning and the rest of the
15 changes to journal.c and recovery.c is for finding the actual tail after
16 mount (since now we are doing "recovery" on every mount) and updating
17 in-memory journal superblock, so that new updates are written at the
18 actual tail of the journal.
20 Note: this patch is still a work in progress. In particular, the
21 jbd2_metamap_insert() function is no longer present. We need to
22 insert things via the new jbd2_transaction_infos_add. -TYT
25 fs/ext4/super.c | 4 ++--
26 fs/jbd2/commit.c | 4 ++--
27 fs/jbd2/journal.c | 11 ++++++-----
28 fs/jbd2/recovery.c | 25 +++++++++++++++++++++----
29 4 files changed, 31 insertions(+), 13 deletions(-)
31 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
32 index b2bd2a31a931..e8e2bbd1e898 100644
35 @@ -4557,8 +4557,8 @@ static int ext4_load_journal(struct super_block *sb,
36 if (!(journal->j_flags & JBD2_BARRIER))
37 ext4_msg(sb, KERN_INFO, "barriers disabled");
39 - if (!ext4_has_feature_journal_needs_recovery(sb))
40 - err = jbd2_journal_wipe(journal, !really_read_only);
41 + /* if (!ext4_has_feature_journal_needs_recovery(sb)) */
42 + /* err = jbd2_journal_wipe(journal, !really_read_only); */
44 char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
46 diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
47 index 50e1a0b375c5..bf61fe5f1048 100644
48 --- a/fs/jbd2/commit.c
49 +++ b/fs/jbd2/commit.c
50 @@ -902,8 +902,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
51 * erase checkpointed transactions from the log by updating journal
55 - jbd2_update_log_tail(journal, first_tid, first_block);
56 + /* if (update_tail) */
57 + /* jbd2_update_log_tail(journal, first_tid, first_block); */
59 /* End of a transaction! Finally, we can do checkpoint
60 processing: any buffers committed as a result of this
61 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
62 index 2d2743297810..e4e3f94e7a93 100644
63 --- a/fs/jbd2/journal.c
64 +++ b/fs/jbd2/journal.c
65 @@ -1296,9 +1296,6 @@ static int journal_reset(journal_t *journal)
67 journal->j_first = first;
68 journal->j_last = last;
70 - journal->j_head = first;
71 - journal->j_tail = first;
72 journal->j_free = last - first;
74 journal->j_tail_sequence = journal->j_transaction_sequence;
75 @@ -1314,12 +1311,15 @@ static int journal_reset(journal_t *journal)
76 * attempting a write to a potential-readonly device.
78 if (sb->s_start == 0) {
79 + journal->j_head = first;
80 + journal->j_tail = first;
81 jbd_debug(1, "JBD2: Skipping superblock update on recovered sb "
82 "(start %ld, seq %d, errno %d)\n",
83 journal->j_tail, journal->j_tail_sequence,
85 journal->j_flags |= JBD2_FLUSHED;
88 /* Lock here to make assertions happy... */
89 mutex_lock(&journal->j_checkpoint_mutex);
91 @@ -1333,6 +1333,7 @@ static int journal_reset(journal_t *journal)
94 mutex_unlock(&journal->j_checkpoint_mutex);
97 return jbd2_journal_start_thread(journal);
99 @@ -1441,8 +1442,8 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
100 jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n",
101 journal->j_tail_sequence);
103 - sb->s_sequence = cpu_to_be32(journal->j_tail_sequence);
104 - sb->s_start = cpu_to_be32(0);
105 + sb->s_sequence = cpu_to_be32(2);
106 + sb->s_start = cpu_to_be32(1);
107 read_unlock(&journal->j_state_lock);
109 jbd2_write_superblock(journal, write_op);
110 diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
111 index da100044566c..30dc632ccf0a 100644
112 --- a/fs/jbd2/recovery.c
113 +++ b/fs/jbd2/recovery.c
114 @@ -32,6 +32,7 @@ struct recovery_info
116 tid_t start_transaction;
117 tid_t end_transaction;
122 @@ -282,6 +283,8 @@ int jbd2_journal_recover(journal_t *journal)
123 /* Restart the log at the next transaction ID, thus invalidating
124 * any existing commit records in the log. */
125 journal->j_transaction_sequence = info.end_transaction;
126 + journal->j_tail = info.tail_block;
127 + journal->j_head = info.tail_block;
129 jbd2_journal_clear_revoke(journal);
130 err2 = sync_blockdev(journal->j_fs_dev);
131 @@ -484,9 +487,6 @@ static int do_one_pass(journal_t *journal,
136 - wrap(journal, next_log_block);
138 /* What kind of buffer is it?
140 * If it is a descriptor block, check that it has the
141 @@ -514,6 +514,9 @@ static int do_one_pass(journal_t *journal,
142 * all of the sequence number checks. What are we going
143 * to do with it? That depends on the pass... */
146 + wrap(journal, next_log_block);
149 case JBD2_DESCRIPTOR_BLOCK:
150 /* Verify checksum first */
151 @@ -578,7 +581,7 @@ static int do_one_pass(journal_t *journal,
152 "block %ld in log\n",
155 - unsigned long long blocknr;
156 + unsigned long long blocknr, log_block;
158 J_ASSERT(obh != NULL);
159 blocknr = read_tag_block(journal,
160 @@ -609,6 +612,19 @@ static int do_one_pass(journal_t *journal,
164 + err = jbd2_journal_bmap(journal,
170 + if (!jbd2_metamap_insert(
177 /* Find a buffer for the new
178 * data being restored */
179 nbh = __getblk(journal->j_fs_dev,
180 @@ -791,6 +807,7 @@ static int do_one_pass(journal_t *journal,
181 if (pass == PASS_SCAN) {
182 if (!info->end_transaction)
183 info->end_transaction = next_commit_ID;
184 + info->tail_block = next_log_block;
186 /* It's really bad news if different passes end up at
187 * different places (but possible due to IO errors). */