add patch preserve-i_mode-if-ext4_set_acl-fails
[ext4-patch-queue.git] / dont-wipe-log-on-unmount
blobad490ac6a538349bfa7a80c60f50ad9e5a5744a0
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
24 ---
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
33 --- a/fs/ext4/super.c
34 +++ b/fs/ext4/super.c
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); */
43         if (!err) {
44                 char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
45                 if (save)
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
52          * superblock.
53          */
54 -       if (update_tail)
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.
77          */
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,
84                         journal->j_errno);
85                 journal->j_flags |= JBD2_FLUSHED;
86         } else {
87 +               #if 0
88                 /* Lock here to make assertions happy... */
89                 mutex_lock(&journal->j_checkpoint_mutex);
90                 /*
91 @@ -1333,6 +1333,7 @@ static int journal_reset(journal_t *journal)
92                                                 journal->j_tail,
93                                                 REQ_FUA);
94                 mutex_unlock(&journal->j_checkpoint_mutex);
95 +               #endif
96         }
97         return jbd2_journal_start_thread(journal);
98  }
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;
118 +       int             tail_block;
120         int             nr_replays;
121         int             nr_revokes;
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,
132                 if (err)
133                         goto failed;
135 -               next_log_block++;
136 -               wrap(journal, next_log_block);
138                 /* What kind of buffer is it?
139                  *
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... */
145 +               next_log_block++;
146 +               wrap(journal, next_log_block);
148                 switch(blocktype) {
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",
153                                                 err, io_block);
154                                 } else {
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,
161                                                 goto skip_write;
162                                         }
164 +                                       err = jbd2_journal_bmap(journal,
165 +                                                               io_block,
166 +                                                               &log_block);
167 +                                       J_ASSERT(!err);
169 +#if 0
170 +                                       if (!jbd2_metamap_insert(
171 +                                                       journal,
172 +                                                       blocknr,
173 +                                                       log_block))
174 +                                               goto failed;
175 +#endif
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;
185         } else {
186                 /* It's really bad news if different passes end up at
187                  * different places (but possible due to IO errors). */