19 #include <linux/time.h>
22 #include <linux/errno.h>
42 static int do_one_pass(journal_t *journal,
44 static int scan_revoke_records(journal_t *,
struct buffer_head *,
50 static void journal_brelse_array(
struct buffer_head *
b[],
int n)
70 static int do_readahead(journal_t *journal,
unsigned int start)
75 struct buffer_head *bh;
77 struct buffer_head *
bufs[MAXBUF];
80 max = start + (128 * 1024 / journal->j_blocksize);
81 if (max > journal->j_maxlen)
82 max = journal->j_maxlen;
89 for (next = start; next <
max; next++) {
98 bh =
__getblk(journal->j_dev, blocknr, journal->j_blocksize);
104 if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
106 if (nbufs == MAXBUF) {
108 journal_brelse_array(bufs, nbufs);
121 journal_brelse_array(bufs, nbufs);
132 static int jread(
struct buffer_head **bhp, journal_t *journal,
137 struct buffer_head *bh;
141 if (offset >= journal->j_maxlen) {
154 bh =
__getblk(journal->j_dev, blocknr, journal->j_blocksize);
158 if (!buffer_uptodate(bh)) {
162 do_readahead(journal, offset);
166 if (!buffer_uptodate(bh)) {
177 static int jbd2_descr_block_csum_verify(journal_t *
j,
181 __u32 provided, calculated;
190 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
194 return provided == calculated;
201 static int count_tags(journal_t *journal,
struct buffer_head *bh)
205 int nr = 0,
size = journal->j_blocksize;
213 while ((tagp - bh->b_data + tag_bytes) <=
size) {
230 #define wrap(journal, var) \
232 if (var >= (journal)->j_last) \
233 var -= ((journal)->j_last - (journal)->j_first); \
255 memset(&info, 0,
sizeof(info));
256 sb = journal->j_superblock;
265 jbd_debug(1,
"No recovery required, last transaction %d\n",
271 err = do_one_pass(journal, &info,
PASS_SCAN);
277 jbd_debug(1,
"JBD2: recovery, exit status %d, "
278 "recovered transactions %u to %u\n",
280 jbd_debug(1,
"JBD2: Replayed %d and revoked %d/%d blocks\n",
292 if (journal->j_flags & JBD2_BARRIER) {
319 memset (&info, 0,
sizeof(info));
321 err = do_one_pass(journal, &info,
PASS_SCAN);
325 ++journal->j_transaction_sequence;
327 #ifdef CONFIG_JBD2_DEBUG
331 "JBD2: ignoring %d transaction%s from the journal.\n",
332 dropped, (dropped == 1) ?
"" :
"s");
353 static int calc_chksums(journal_t *journal,
struct buffer_head *bh,
354 unsigned long *next_log_block,
__u32 *crc32_sum)
356 int i, num_blks,
err;
357 unsigned long io_block;
358 struct buffer_head *obh;
360 num_blks = count_tags(journal, bh);
362 *crc32_sum =
crc32_be(*crc32_sum, (
void *)bh->b_data, bh->b_size);
364 for (i = 0; i < num_blks; i++) {
365 io_block = (*next_log_block)++;
366 wrap(journal, *next_log_block);
367 err = jread(&obh, journal, io_block);
370 "%lu in log\n", err, io_block);
373 *crc32_sum =
crc32_be(*crc32_sum, (
void *)obh->b_data,
381 static int jbd2_commit_block_csum_verify(journal_t *j,
void *buf)
384 __u32 provided, calculated;
392 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
396 return provided == calculated;
402 __u32 provided, calculated;
408 calculated = jbd2_chksum(j, j->j_csum_seed, (
__u8 *)&sequence,
410 calculated = jbd2_chksum(j, calculated, buf, j->j_blocksize);
416 static int do_one_pass(journal_t *journal,
419 unsigned int first_commit_ID, next_commit_ID;
420 unsigned long next_log_block;
421 int err, success = 0;
424 struct buffer_head * bh;
428 __u32 crc32_sum = ~0;
429 int descr_csum_size = 0;
437 sb = journal->j_superblock;
441 first_commit_ID = next_commit_ID;
445 jbd_debug(1,
"Starting recovery pass %d\n", pass);
458 struct buffer_head * obh;
459 struct buffer_head * nbh;
471 jbd_debug(2,
"Scanning for sequence ID %u at %lu/%lu\n",
472 next_commit_ID, next_log_block, journal->j_last);
478 jbd_debug(3,
"JBD2: checking block %ld\n", next_log_block);
479 err = jread(&bh, journal, next_log_block);
484 wrap(journal, next_log_block);
501 jbd_debug(3,
"Found magic %d, sequence %d\n",
502 blocktype, sequence);
504 if (sequence != next_commit_ID) {
520 if (descr_csum_size > 0 &&
521 !jbd2_descr_block_csum_verify(journal,
536 if (calc_chksums(journal, bh,
545 next_log_block += count_tags(journal, bh);
546 wrap(journal, next_log_block);
556 while ((tagp - bh->b_data + tag_bytes)
557 <= journal->j_blocksize - descr_csum_size) {
558 unsigned long io_block;
563 io_block = next_log_block++;
564 wrap(journal, next_log_block);
565 err = jread(&obh, journal, io_block);
571 "JBD2: IO error %d recovering "
572 "block %ld in log\n",
577 J_ASSERT(obh !=
NULL);
578 blocknr = read_tag_block(tag_bytes,
593 if (!jbd2_block_tag_csum_verify(
594 journal, tag, obh->b_data,
599 "checksum recovering "
600 "block %llu in log\n",
609 journal->j_blocksize);
612 "JBD2: Out of memory "
613 "during recovery.\n");
621 memcpy(nbh->b_data, obh->b_data,
622 journal->j_blocksize);
624 *((
__be32 *)nbh->b_data) =
628 BUFFER_TRACE(nbh,
"marking dirty");
629 set_buffer_uptodate(nbh);
631 BUFFER_TRACE(nbh,
"marking uptodate");
690 int chksum_err, chksum_seen;
693 unsigned found_chksum =
696 chksum_err = chksum_seen = 0;
699 journal->j_failed_commit =
705 if (crc32_sum == found_chksum &&
731 journal->j_failed_commit =
740 !jbd2_commit_block_csum_verify(journal,
746 journal->j_failed_commit =
764 err = scan_revoke_records(journal, bh,
765 next_commit_ID, info);
772 jbd_debug(3,
"Unrecognised magic %d, end of scan.\n",
795 "transaction %u, expected %u\n",
808 static int jbd2_revoke_block_csum_verify(journal_t *j,
812 __u32 provided, calculated;
821 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
825 return provided == calculated;
830 static int scan_revoke_records(journal_t *journal,
struct buffer_head *bh,
841 if (!jbd2_revoke_block_csum_verify(journal, header))
847 while (offset + record_len <= max) {
855 offset += record_len;