1470decc6SDave Kleikamp /* 2470decc6SDave Kleikamp * linux/fs/recovery.c 3470decc6SDave Kleikamp * 4470decc6SDave Kleikamp * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 5470decc6SDave Kleikamp * 6470decc6SDave Kleikamp * Copyright 1999-2000 Red Hat Software --- All Rights Reserved 7470decc6SDave Kleikamp * 8470decc6SDave Kleikamp * This file is part of the Linux kernel and is made available under 9470decc6SDave Kleikamp * the terms of the GNU General Public License, version 2, or at your 10470decc6SDave Kleikamp * option, any later version, incorporated herein by reference. 11470decc6SDave Kleikamp * 12470decc6SDave Kleikamp * Journal recovery routines for the generic filesystem journaling code; 13470decc6SDave Kleikamp * part of the ext2fs journaling system. 14470decc6SDave Kleikamp */ 15470decc6SDave Kleikamp 16470decc6SDave Kleikamp #ifndef __KERNEL__ 17470decc6SDave Kleikamp #include "jfs_user.h" 18470decc6SDave Kleikamp #else 19470decc6SDave Kleikamp #include <linux/time.h> 20470decc6SDave Kleikamp #include <linux/fs.h> 21f7f4bccbSMingming Cao #include <linux/jbd2.h> 22470decc6SDave Kleikamp #include <linux/errno.h> 23470decc6SDave Kleikamp #include <linux/slab.h> 24470decc6SDave Kleikamp #endif 25470decc6SDave Kleikamp 26470decc6SDave Kleikamp /* 27470decc6SDave Kleikamp * Maintain information about the progress of the recovery job, so that 28470decc6SDave Kleikamp * the different passes can carry information between them. 29470decc6SDave Kleikamp */ 30470decc6SDave Kleikamp struct recovery_info 31470decc6SDave Kleikamp { 32470decc6SDave Kleikamp tid_t start_transaction; 33470decc6SDave Kleikamp tid_t end_transaction; 34470decc6SDave Kleikamp 35470decc6SDave Kleikamp int nr_replays; 36470decc6SDave Kleikamp int nr_revokes; 37470decc6SDave Kleikamp int nr_revoke_hits; 38470decc6SDave Kleikamp }; 39470decc6SDave Kleikamp 40470decc6SDave Kleikamp enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY}; 41470decc6SDave Kleikamp static int do_one_pass(journal_t *journal, 42470decc6SDave Kleikamp struct recovery_info *info, enum passtype pass); 43470decc6SDave Kleikamp static int scan_revoke_records(journal_t *, struct buffer_head *, 44470decc6SDave Kleikamp tid_t, struct recovery_info *); 45470decc6SDave Kleikamp 46470decc6SDave Kleikamp #ifdef __KERNEL__ 47470decc6SDave Kleikamp 48470decc6SDave Kleikamp /* Release readahead buffers after use */ 49470decc6SDave Kleikamp static void journal_brelse_array(struct buffer_head *b[], int n) 50470decc6SDave Kleikamp { 51470decc6SDave Kleikamp while (--n >= 0) 52470decc6SDave Kleikamp brelse (b[n]); 53470decc6SDave Kleikamp } 54470decc6SDave Kleikamp 55470decc6SDave Kleikamp 56470decc6SDave Kleikamp /* 57470decc6SDave Kleikamp * When reading from the journal, we are going through the block device 58470decc6SDave Kleikamp * layer directly and so there is no readahead being done for us. We 59470decc6SDave Kleikamp * need to implement any readahead ourselves if we want it to happen at 60470decc6SDave Kleikamp * all. Recovery is basically one long sequential read, so make sure we 61470decc6SDave Kleikamp * do the IO in reasonably large chunks. 62470decc6SDave Kleikamp * 63470decc6SDave Kleikamp * This is not so critical that we need to be enormously clever about 64470decc6SDave Kleikamp * the readahead size, though. 128K is a purely arbitrary, good-enough 65470decc6SDave Kleikamp * fixed value. 66470decc6SDave Kleikamp */ 67470decc6SDave Kleikamp 68470decc6SDave Kleikamp #define MAXBUF 8 69470decc6SDave Kleikamp static int do_readahead(journal_t *journal, unsigned int start) 70470decc6SDave Kleikamp { 71470decc6SDave Kleikamp int err; 72470decc6SDave Kleikamp unsigned int max, nbufs, next; 73470decc6SDave Kleikamp unsigned long blocknr; 74470decc6SDave Kleikamp struct buffer_head *bh; 75470decc6SDave Kleikamp 76470decc6SDave Kleikamp struct buffer_head * bufs[MAXBUF]; 77470decc6SDave Kleikamp 78470decc6SDave Kleikamp /* Do up to 128K of readahead */ 79470decc6SDave Kleikamp max = start + (128 * 1024 / journal->j_blocksize); 80470decc6SDave Kleikamp if (max > journal->j_maxlen) 81470decc6SDave Kleikamp max = journal->j_maxlen; 82470decc6SDave Kleikamp 83470decc6SDave Kleikamp /* Do the readahead itself. We'll submit MAXBUF buffer_heads at 84470decc6SDave Kleikamp * a time to the block device IO layer. */ 85470decc6SDave Kleikamp 86470decc6SDave Kleikamp nbufs = 0; 87470decc6SDave Kleikamp 88470decc6SDave Kleikamp for (next = start; next < max; next++) { 89f7f4bccbSMingming Cao err = jbd2_journal_bmap(journal, next, &blocknr); 90470decc6SDave Kleikamp 91470decc6SDave Kleikamp if (err) { 92470decc6SDave Kleikamp printk (KERN_ERR "JBD: bad block at offset %u\n", 93470decc6SDave Kleikamp next); 94470decc6SDave Kleikamp goto failed; 95470decc6SDave Kleikamp } 96470decc6SDave Kleikamp 97470decc6SDave Kleikamp bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); 98470decc6SDave Kleikamp if (!bh) { 99470decc6SDave Kleikamp err = -ENOMEM; 100470decc6SDave Kleikamp goto failed; 101470decc6SDave Kleikamp } 102470decc6SDave Kleikamp 103470decc6SDave Kleikamp if (!buffer_uptodate(bh) && !buffer_locked(bh)) { 104470decc6SDave Kleikamp bufs[nbufs++] = bh; 105470decc6SDave Kleikamp if (nbufs == MAXBUF) { 106470decc6SDave Kleikamp ll_rw_block(READ, nbufs, bufs); 107470decc6SDave Kleikamp journal_brelse_array(bufs, nbufs); 108470decc6SDave Kleikamp nbufs = 0; 109470decc6SDave Kleikamp } 110470decc6SDave Kleikamp } else 111470decc6SDave Kleikamp brelse(bh); 112470decc6SDave Kleikamp } 113470decc6SDave Kleikamp 114470decc6SDave Kleikamp if (nbufs) 115470decc6SDave Kleikamp ll_rw_block(READ, nbufs, bufs); 116470decc6SDave Kleikamp err = 0; 117470decc6SDave Kleikamp 118470decc6SDave Kleikamp failed: 119470decc6SDave Kleikamp if (nbufs) 120470decc6SDave Kleikamp journal_brelse_array(bufs, nbufs); 121470decc6SDave Kleikamp return err; 122470decc6SDave Kleikamp } 123470decc6SDave Kleikamp 124470decc6SDave Kleikamp #endif /* __KERNEL__ */ 125470decc6SDave Kleikamp 126470decc6SDave Kleikamp 127470decc6SDave Kleikamp /* 128470decc6SDave Kleikamp * Read a block from the journal 129470decc6SDave Kleikamp */ 130470decc6SDave Kleikamp 131470decc6SDave Kleikamp static int jread(struct buffer_head **bhp, journal_t *journal, 132470decc6SDave Kleikamp unsigned int offset) 133470decc6SDave Kleikamp { 134470decc6SDave Kleikamp int err; 135470decc6SDave Kleikamp unsigned long blocknr; 136470decc6SDave Kleikamp struct buffer_head *bh; 137470decc6SDave Kleikamp 138470decc6SDave Kleikamp *bhp = NULL; 139470decc6SDave Kleikamp 140470decc6SDave Kleikamp if (offset >= journal->j_maxlen) { 141470decc6SDave Kleikamp printk(KERN_ERR "JBD: corrupted journal superblock\n"); 142470decc6SDave Kleikamp return -EIO; 143470decc6SDave Kleikamp } 144470decc6SDave Kleikamp 145f7f4bccbSMingming Cao err = jbd2_journal_bmap(journal, offset, &blocknr); 146470decc6SDave Kleikamp 147470decc6SDave Kleikamp if (err) { 148470decc6SDave Kleikamp printk (KERN_ERR "JBD: bad block at offset %u\n", 149470decc6SDave Kleikamp offset); 150470decc6SDave Kleikamp return err; 151470decc6SDave Kleikamp } 152470decc6SDave Kleikamp 153470decc6SDave Kleikamp bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); 154470decc6SDave Kleikamp if (!bh) 155470decc6SDave Kleikamp return -ENOMEM; 156470decc6SDave Kleikamp 157470decc6SDave Kleikamp if (!buffer_uptodate(bh)) { 158470decc6SDave Kleikamp /* If this is a brand new buffer, start readahead. 159470decc6SDave Kleikamp Otherwise, we assume we are already reading it. */ 160470decc6SDave Kleikamp if (!buffer_req(bh)) 161470decc6SDave Kleikamp do_readahead(journal, offset); 162470decc6SDave Kleikamp wait_on_buffer(bh); 163470decc6SDave Kleikamp } 164470decc6SDave Kleikamp 165470decc6SDave Kleikamp if (!buffer_uptodate(bh)) { 166470decc6SDave Kleikamp printk (KERN_ERR "JBD: Failed to read block at offset %u\n", 167470decc6SDave Kleikamp offset); 168470decc6SDave Kleikamp brelse(bh); 169470decc6SDave Kleikamp return -EIO; 170470decc6SDave Kleikamp } 171470decc6SDave Kleikamp 172470decc6SDave Kleikamp *bhp = bh; 173470decc6SDave Kleikamp return 0; 174470decc6SDave Kleikamp } 175470decc6SDave Kleikamp 176470decc6SDave Kleikamp 177470decc6SDave Kleikamp /* 178470decc6SDave Kleikamp * Count the number of in-use tags in a journal descriptor block. 179470decc6SDave Kleikamp */ 180470decc6SDave Kleikamp 181*b517bea1SZach Brown static int count_tags(journal_t *journal, struct buffer_head *bh) 182470decc6SDave Kleikamp { 183470decc6SDave Kleikamp char * tagp; 184470decc6SDave Kleikamp journal_block_tag_t * tag; 185*b517bea1SZach Brown int nr = 0, size = journal->j_blocksize; 186*b517bea1SZach Brown int tag_bytes = journal_tag_bytes(journal); 187470decc6SDave Kleikamp 188470decc6SDave Kleikamp tagp = &bh->b_data[sizeof(journal_header_t)]; 189470decc6SDave Kleikamp 190*b517bea1SZach Brown while ((tagp - bh->b_data + tag_bytes) <= size) { 191470decc6SDave Kleikamp tag = (journal_block_tag_t *) tagp; 192470decc6SDave Kleikamp 193470decc6SDave Kleikamp nr++; 194*b517bea1SZach Brown tagp += tag_bytes; 195f7f4bccbSMingming Cao if (!(tag->t_flags & cpu_to_be32(JBD2_FLAG_SAME_UUID))) 196470decc6SDave Kleikamp tagp += 16; 197470decc6SDave Kleikamp 198f7f4bccbSMingming Cao if (tag->t_flags & cpu_to_be32(JBD2_FLAG_LAST_TAG)) 199470decc6SDave Kleikamp break; 200470decc6SDave Kleikamp } 201470decc6SDave Kleikamp 202470decc6SDave Kleikamp return nr; 203470decc6SDave Kleikamp } 204470decc6SDave Kleikamp 205470decc6SDave Kleikamp 206470decc6SDave Kleikamp /* Make sure we wrap around the log correctly! */ 207470decc6SDave Kleikamp #define wrap(journal, var) \ 208470decc6SDave Kleikamp do { \ 209470decc6SDave Kleikamp if (var >= (journal)->j_last) \ 210470decc6SDave Kleikamp var -= ((journal)->j_last - (journal)->j_first); \ 211470decc6SDave Kleikamp } while (0) 212470decc6SDave Kleikamp 213470decc6SDave Kleikamp /** 214f7f4bccbSMingming Cao * jbd2_journal_recover - recovers a on-disk journal 215470decc6SDave Kleikamp * @journal: the journal to recover 216470decc6SDave Kleikamp * 217470decc6SDave Kleikamp * The primary function for recovering the log contents when mounting a 218470decc6SDave Kleikamp * journaled device. 219470decc6SDave Kleikamp * 220470decc6SDave Kleikamp * Recovery is done in three passes. In the first pass, we look for the 221470decc6SDave Kleikamp * end of the log. In the second, we assemble the list of revoke 222470decc6SDave Kleikamp * blocks. In the third and final pass, we replay any un-revoked blocks 223470decc6SDave Kleikamp * in the log. 224470decc6SDave Kleikamp */ 225f7f4bccbSMingming Cao int jbd2_journal_recover(journal_t *journal) 226470decc6SDave Kleikamp { 227470decc6SDave Kleikamp int err; 228470decc6SDave Kleikamp journal_superblock_t * sb; 229470decc6SDave Kleikamp 230470decc6SDave Kleikamp struct recovery_info info; 231470decc6SDave Kleikamp 232470decc6SDave Kleikamp memset(&info, 0, sizeof(info)); 233470decc6SDave Kleikamp sb = journal->j_superblock; 234470decc6SDave Kleikamp 235470decc6SDave Kleikamp /* 236470decc6SDave Kleikamp * The journal superblock's s_start field (the current log head) 237470decc6SDave Kleikamp * is always zero if, and only if, the journal was cleanly 238470decc6SDave Kleikamp * unmounted. 239470decc6SDave Kleikamp */ 240470decc6SDave Kleikamp 241470decc6SDave Kleikamp if (!sb->s_start) { 242470decc6SDave Kleikamp jbd_debug(1, "No recovery required, last transaction %d\n", 243470decc6SDave Kleikamp be32_to_cpu(sb->s_sequence)); 244470decc6SDave Kleikamp journal->j_transaction_sequence = be32_to_cpu(sb->s_sequence) + 1; 245470decc6SDave Kleikamp return 0; 246470decc6SDave Kleikamp } 247470decc6SDave Kleikamp 248470decc6SDave Kleikamp err = do_one_pass(journal, &info, PASS_SCAN); 249470decc6SDave Kleikamp if (!err) 250470decc6SDave Kleikamp err = do_one_pass(journal, &info, PASS_REVOKE); 251470decc6SDave Kleikamp if (!err) 252470decc6SDave Kleikamp err = do_one_pass(journal, &info, PASS_REPLAY); 253470decc6SDave Kleikamp 254470decc6SDave Kleikamp jbd_debug(0, "JBD: recovery, exit status %d, " 255470decc6SDave Kleikamp "recovered transactions %u to %u\n", 256470decc6SDave Kleikamp err, info.start_transaction, info.end_transaction); 257470decc6SDave Kleikamp jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n", 258470decc6SDave Kleikamp info.nr_replays, info.nr_revoke_hits, info.nr_revokes); 259470decc6SDave Kleikamp 260470decc6SDave Kleikamp /* Restart the log at the next transaction ID, thus invalidating 261470decc6SDave Kleikamp * any existing commit records in the log. */ 262470decc6SDave Kleikamp journal->j_transaction_sequence = ++info.end_transaction; 263470decc6SDave Kleikamp 264f7f4bccbSMingming Cao jbd2_journal_clear_revoke(journal); 265470decc6SDave Kleikamp sync_blockdev(journal->j_fs_dev); 266470decc6SDave Kleikamp return err; 267470decc6SDave Kleikamp } 268470decc6SDave Kleikamp 269470decc6SDave Kleikamp /** 270f7f4bccbSMingming Cao * jbd2_journal_skip_recovery - Start journal and wipe exiting records 271470decc6SDave Kleikamp * @journal: journal to startup 272470decc6SDave Kleikamp * 273470decc6SDave Kleikamp * Locate any valid recovery information from the journal and set up the 274470decc6SDave Kleikamp * journal structures in memory to ignore it (presumably because the 275470decc6SDave Kleikamp * caller has evidence that it is out of date). 276470decc6SDave Kleikamp * This function does'nt appear to be exorted.. 277470decc6SDave Kleikamp * 278470decc6SDave Kleikamp * We perform one pass over the journal to allow us to tell the user how 279470decc6SDave Kleikamp * much recovery information is being erased, and to let us initialise 280470decc6SDave Kleikamp * the journal transaction sequence numbers to the next unused ID. 281470decc6SDave Kleikamp */ 282f7f4bccbSMingming Cao int jbd2_journal_skip_recovery(journal_t *journal) 283470decc6SDave Kleikamp { 284470decc6SDave Kleikamp int err; 285470decc6SDave Kleikamp journal_superblock_t * sb; 286470decc6SDave Kleikamp 287470decc6SDave Kleikamp struct recovery_info info; 288470decc6SDave Kleikamp 289470decc6SDave Kleikamp memset (&info, 0, sizeof(info)); 290470decc6SDave Kleikamp sb = journal->j_superblock; 291470decc6SDave Kleikamp 292470decc6SDave Kleikamp err = do_one_pass(journal, &info, PASS_SCAN); 293470decc6SDave Kleikamp 294470decc6SDave Kleikamp if (err) { 295470decc6SDave Kleikamp printk(KERN_ERR "JBD: error %d scanning journal\n", err); 296470decc6SDave Kleikamp ++journal->j_transaction_sequence; 297470decc6SDave Kleikamp } else { 298470decc6SDave Kleikamp #ifdef CONFIG_JBD_DEBUG 299470decc6SDave Kleikamp int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); 300470decc6SDave Kleikamp #endif 301470decc6SDave Kleikamp jbd_debug(0, 302470decc6SDave Kleikamp "JBD: ignoring %d transaction%s from the journal.\n", 303470decc6SDave Kleikamp dropped, (dropped == 1) ? "" : "s"); 304470decc6SDave Kleikamp journal->j_transaction_sequence = ++info.end_transaction; 305470decc6SDave Kleikamp } 306470decc6SDave Kleikamp 307470decc6SDave Kleikamp journal->j_tail = 0; 308470decc6SDave Kleikamp return err; 309470decc6SDave Kleikamp } 310470decc6SDave Kleikamp 311*b517bea1SZach Brown static inline sector_t read_tag_block(int tag_bytes, journal_block_tag_t *tag) 312*b517bea1SZach Brown { 313*b517bea1SZach Brown sector_t block = be32_to_cpu(tag->t_blocknr); 314*b517bea1SZach Brown if (tag_bytes > JBD_TAG_SIZE32) 315*b517bea1SZach Brown block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32; 316*b517bea1SZach Brown return block; 317*b517bea1SZach Brown } 318*b517bea1SZach Brown 319470decc6SDave Kleikamp static int do_one_pass(journal_t *journal, 320470decc6SDave Kleikamp struct recovery_info *info, enum passtype pass) 321470decc6SDave Kleikamp { 322470decc6SDave Kleikamp unsigned int first_commit_ID, next_commit_ID; 323470decc6SDave Kleikamp unsigned long next_log_block; 324470decc6SDave Kleikamp int err, success = 0; 325470decc6SDave Kleikamp journal_superblock_t * sb; 326470decc6SDave Kleikamp journal_header_t * tmp; 327470decc6SDave Kleikamp struct buffer_head * bh; 328470decc6SDave Kleikamp unsigned int sequence; 329470decc6SDave Kleikamp int blocktype; 330*b517bea1SZach Brown int tag_bytes = journal_tag_bytes(journal); 331470decc6SDave Kleikamp 332470decc6SDave Kleikamp /* Precompute the maximum metadata descriptors in a descriptor block */ 333470decc6SDave Kleikamp int MAX_BLOCKS_PER_DESC; 334470decc6SDave Kleikamp MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t)) 335*b517bea1SZach Brown / tag_bytes); 336470decc6SDave Kleikamp 337470decc6SDave Kleikamp /* 338470decc6SDave Kleikamp * First thing is to establish what we expect to find in the log 339470decc6SDave Kleikamp * (in terms of transaction IDs), and where (in terms of log 340470decc6SDave Kleikamp * block offsets): query the superblock. 341470decc6SDave Kleikamp */ 342470decc6SDave Kleikamp 343470decc6SDave Kleikamp sb = journal->j_superblock; 344470decc6SDave Kleikamp next_commit_ID = be32_to_cpu(sb->s_sequence); 345470decc6SDave Kleikamp next_log_block = be32_to_cpu(sb->s_start); 346470decc6SDave Kleikamp 347470decc6SDave Kleikamp first_commit_ID = next_commit_ID; 348470decc6SDave Kleikamp if (pass == PASS_SCAN) 349470decc6SDave Kleikamp info->start_transaction = first_commit_ID; 350470decc6SDave Kleikamp 351470decc6SDave Kleikamp jbd_debug(1, "Starting recovery pass %d\n", pass); 352470decc6SDave Kleikamp 353470decc6SDave Kleikamp /* 354470decc6SDave Kleikamp * Now we walk through the log, transaction by transaction, 355470decc6SDave Kleikamp * making sure that each transaction has a commit block in the 356470decc6SDave Kleikamp * expected place. Each complete transaction gets replayed back 357470decc6SDave Kleikamp * into the main filesystem. 358470decc6SDave Kleikamp */ 359470decc6SDave Kleikamp 360470decc6SDave Kleikamp while (1) { 361470decc6SDave Kleikamp int flags; 362470decc6SDave Kleikamp char * tagp; 363470decc6SDave Kleikamp journal_block_tag_t * tag; 364470decc6SDave Kleikamp struct buffer_head * obh; 365470decc6SDave Kleikamp struct buffer_head * nbh; 366470decc6SDave Kleikamp 367470decc6SDave Kleikamp cond_resched(); /* We're under lock_kernel() */ 368470decc6SDave Kleikamp 369470decc6SDave Kleikamp /* If we already know where to stop the log traversal, 370470decc6SDave Kleikamp * check right now that we haven't gone past the end of 371470decc6SDave Kleikamp * the log. */ 372470decc6SDave Kleikamp 373470decc6SDave Kleikamp if (pass != PASS_SCAN) 374470decc6SDave Kleikamp if (tid_geq(next_commit_ID, info->end_transaction)) 375470decc6SDave Kleikamp break; 376470decc6SDave Kleikamp 377470decc6SDave Kleikamp jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", 378470decc6SDave Kleikamp next_commit_ID, next_log_block, journal->j_last); 379470decc6SDave Kleikamp 380470decc6SDave Kleikamp /* Skip over each chunk of the transaction looking 381470decc6SDave Kleikamp * either the next descriptor block or the final commit 382470decc6SDave Kleikamp * record. */ 383470decc6SDave Kleikamp 384470decc6SDave Kleikamp jbd_debug(3, "JBD: checking block %ld\n", next_log_block); 385470decc6SDave Kleikamp err = jread(&bh, journal, next_log_block); 386470decc6SDave Kleikamp if (err) 387470decc6SDave Kleikamp goto failed; 388470decc6SDave Kleikamp 389470decc6SDave Kleikamp next_log_block++; 390470decc6SDave Kleikamp wrap(journal, next_log_block); 391470decc6SDave Kleikamp 392470decc6SDave Kleikamp /* What kind of buffer is it? 393470decc6SDave Kleikamp * 394470decc6SDave Kleikamp * If it is a descriptor block, check that it has the 395470decc6SDave Kleikamp * expected sequence number. Otherwise, we're all done 396470decc6SDave Kleikamp * here. */ 397470decc6SDave Kleikamp 398470decc6SDave Kleikamp tmp = (journal_header_t *)bh->b_data; 399470decc6SDave Kleikamp 400f7f4bccbSMingming Cao if (tmp->h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER)) { 401470decc6SDave Kleikamp brelse(bh); 402470decc6SDave Kleikamp break; 403470decc6SDave Kleikamp } 404470decc6SDave Kleikamp 405470decc6SDave Kleikamp blocktype = be32_to_cpu(tmp->h_blocktype); 406470decc6SDave Kleikamp sequence = be32_to_cpu(tmp->h_sequence); 407470decc6SDave Kleikamp jbd_debug(3, "Found magic %d, sequence %d\n", 408470decc6SDave Kleikamp blocktype, sequence); 409470decc6SDave Kleikamp 410470decc6SDave Kleikamp if (sequence != next_commit_ID) { 411470decc6SDave Kleikamp brelse(bh); 412470decc6SDave Kleikamp break; 413470decc6SDave Kleikamp } 414470decc6SDave Kleikamp 415470decc6SDave Kleikamp /* OK, we have a valid descriptor block which matches 416470decc6SDave Kleikamp * all of the sequence number checks. What are we going 417470decc6SDave Kleikamp * to do with it? That depends on the pass... */ 418470decc6SDave Kleikamp 419470decc6SDave Kleikamp switch(blocktype) { 420f7f4bccbSMingming Cao case JBD2_DESCRIPTOR_BLOCK: 421470decc6SDave Kleikamp /* If it is a valid descriptor block, replay it 422470decc6SDave Kleikamp * in pass REPLAY; otherwise, just skip over the 423470decc6SDave Kleikamp * blocks it describes. */ 424470decc6SDave Kleikamp if (pass != PASS_REPLAY) { 425*b517bea1SZach Brown next_log_block += count_tags(journal, bh); 426470decc6SDave Kleikamp wrap(journal, next_log_block); 427470decc6SDave Kleikamp brelse(bh); 428470decc6SDave Kleikamp continue; 429470decc6SDave Kleikamp } 430470decc6SDave Kleikamp 431470decc6SDave Kleikamp /* A descriptor block: we can now write all of 432470decc6SDave Kleikamp * the data blocks. Yay, useful work is finally 433470decc6SDave Kleikamp * getting done here! */ 434470decc6SDave Kleikamp 435470decc6SDave Kleikamp tagp = &bh->b_data[sizeof(journal_header_t)]; 436*b517bea1SZach Brown while ((tagp - bh->b_data + tag_bytes) 437470decc6SDave Kleikamp <= journal->j_blocksize) { 438470decc6SDave Kleikamp unsigned long io_block; 439470decc6SDave Kleikamp 440470decc6SDave Kleikamp tag = (journal_block_tag_t *) tagp; 441470decc6SDave Kleikamp flags = be32_to_cpu(tag->t_flags); 442470decc6SDave Kleikamp 443470decc6SDave Kleikamp io_block = next_log_block++; 444470decc6SDave Kleikamp wrap(journal, next_log_block); 445470decc6SDave Kleikamp err = jread(&obh, journal, io_block); 446470decc6SDave Kleikamp if (err) { 447470decc6SDave Kleikamp /* Recover what we can, but 448470decc6SDave Kleikamp * report failure at the end. */ 449470decc6SDave Kleikamp success = err; 450470decc6SDave Kleikamp printk (KERN_ERR 451470decc6SDave Kleikamp "JBD: IO error %d recovering " 452470decc6SDave Kleikamp "block %ld in log\n", 453470decc6SDave Kleikamp err, io_block); 454470decc6SDave Kleikamp } else { 455470decc6SDave Kleikamp unsigned long blocknr; 456470decc6SDave Kleikamp 457470decc6SDave Kleikamp J_ASSERT(obh != NULL); 458*b517bea1SZach Brown blocknr = read_tag_block(tag_bytes, 459*b517bea1SZach Brown tag); 460470decc6SDave Kleikamp 461470decc6SDave Kleikamp /* If the block has been 462470decc6SDave Kleikamp * revoked, then we're all done 463470decc6SDave Kleikamp * here. */ 464f7f4bccbSMingming Cao if (jbd2_journal_test_revoke 465470decc6SDave Kleikamp (journal, blocknr, 466470decc6SDave Kleikamp next_commit_ID)) { 467470decc6SDave Kleikamp brelse(obh); 468470decc6SDave Kleikamp ++info->nr_revoke_hits; 469470decc6SDave Kleikamp goto skip_write; 470470decc6SDave Kleikamp } 471470decc6SDave Kleikamp 472470decc6SDave Kleikamp /* Find a buffer for the new 473470decc6SDave Kleikamp * data being restored */ 474470decc6SDave Kleikamp nbh = __getblk(journal->j_fs_dev, 475470decc6SDave Kleikamp blocknr, 476470decc6SDave Kleikamp journal->j_blocksize); 477470decc6SDave Kleikamp if (nbh == NULL) { 478470decc6SDave Kleikamp printk(KERN_ERR 479470decc6SDave Kleikamp "JBD: Out of memory " 480470decc6SDave Kleikamp "during recovery.\n"); 481470decc6SDave Kleikamp err = -ENOMEM; 482470decc6SDave Kleikamp brelse(bh); 483470decc6SDave Kleikamp brelse(obh); 484470decc6SDave Kleikamp goto failed; 485470decc6SDave Kleikamp } 486470decc6SDave Kleikamp 487470decc6SDave Kleikamp lock_buffer(nbh); 488470decc6SDave Kleikamp memcpy(nbh->b_data, obh->b_data, 489470decc6SDave Kleikamp journal->j_blocksize); 490f7f4bccbSMingming Cao if (flags & JBD2_FLAG_ESCAPE) { 491470decc6SDave Kleikamp *((__be32 *)bh->b_data) = 492f7f4bccbSMingming Cao cpu_to_be32(JBD2_MAGIC_NUMBER); 493470decc6SDave Kleikamp } 494470decc6SDave Kleikamp 495470decc6SDave Kleikamp BUFFER_TRACE(nbh, "marking dirty"); 496470decc6SDave Kleikamp set_buffer_uptodate(nbh); 497470decc6SDave Kleikamp mark_buffer_dirty(nbh); 498470decc6SDave Kleikamp BUFFER_TRACE(nbh, "marking uptodate"); 499470decc6SDave Kleikamp ++info->nr_replays; 500470decc6SDave Kleikamp /* ll_rw_block(WRITE, 1, &nbh); */ 501470decc6SDave Kleikamp unlock_buffer(nbh); 502470decc6SDave Kleikamp brelse(obh); 503470decc6SDave Kleikamp brelse(nbh); 504470decc6SDave Kleikamp } 505470decc6SDave Kleikamp 506470decc6SDave Kleikamp skip_write: 507*b517bea1SZach Brown tagp += tag_bytes; 508f7f4bccbSMingming Cao if (!(flags & JBD2_FLAG_SAME_UUID)) 509470decc6SDave Kleikamp tagp += 16; 510470decc6SDave Kleikamp 511f7f4bccbSMingming Cao if (flags & JBD2_FLAG_LAST_TAG) 512470decc6SDave Kleikamp break; 513470decc6SDave Kleikamp } 514470decc6SDave Kleikamp 515470decc6SDave Kleikamp brelse(bh); 516470decc6SDave Kleikamp continue; 517470decc6SDave Kleikamp 518f7f4bccbSMingming Cao case JBD2_COMMIT_BLOCK: 519470decc6SDave Kleikamp /* Found an expected commit block: not much to 520470decc6SDave Kleikamp * do other than move on to the next sequence 521470decc6SDave Kleikamp * number. */ 522470decc6SDave Kleikamp brelse(bh); 523470decc6SDave Kleikamp next_commit_ID++; 524470decc6SDave Kleikamp continue; 525470decc6SDave Kleikamp 526f7f4bccbSMingming Cao case JBD2_REVOKE_BLOCK: 527470decc6SDave Kleikamp /* If we aren't in the REVOKE pass, then we can 528470decc6SDave Kleikamp * just skip over this block. */ 529470decc6SDave Kleikamp if (pass != PASS_REVOKE) { 530470decc6SDave Kleikamp brelse(bh); 531470decc6SDave Kleikamp continue; 532470decc6SDave Kleikamp } 533470decc6SDave Kleikamp 534470decc6SDave Kleikamp err = scan_revoke_records(journal, bh, 535470decc6SDave Kleikamp next_commit_ID, info); 536470decc6SDave Kleikamp brelse(bh); 537470decc6SDave Kleikamp if (err) 538470decc6SDave Kleikamp goto failed; 539470decc6SDave Kleikamp continue; 540470decc6SDave Kleikamp 541470decc6SDave Kleikamp default: 542470decc6SDave Kleikamp jbd_debug(3, "Unrecognised magic %d, end of scan.\n", 543470decc6SDave Kleikamp blocktype); 544470decc6SDave Kleikamp brelse(bh); 545470decc6SDave Kleikamp goto done; 546470decc6SDave Kleikamp } 547470decc6SDave Kleikamp } 548470decc6SDave Kleikamp 549470decc6SDave Kleikamp done: 550470decc6SDave Kleikamp /* 551470decc6SDave Kleikamp * We broke out of the log scan loop: either we came to the 552470decc6SDave Kleikamp * known end of the log or we found an unexpected block in the 553470decc6SDave Kleikamp * log. If the latter happened, then we know that the "current" 554470decc6SDave Kleikamp * transaction marks the end of the valid log. 555470decc6SDave Kleikamp */ 556470decc6SDave Kleikamp 557470decc6SDave Kleikamp if (pass == PASS_SCAN) 558470decc6SDave Kleikamp info->end_transaction = next_commit_ID; 559470decc6SDave Kleikamp else { 560470decc6SDave Kleikamp /* It's really bad news if different passes end up at 561470decc6SDave Kleikamp * different places (but possible due to IO errors). */ 562470decc6SDave Kleikamp if (info->end_transaction != next_commit_ID) { 563470decc6SDave Kleikamp printk (KERN_ERR "JBD: recovery pass %d ended at " 564470decc6SDave Kleikamp "transaction %u, expected %u\n", 565470decc6SDave Kleikamp pass, next_commit_ID, info->end_transaction); 566470decc6SDave Kleikamp if (!success) 567470decc6SDave Kleikamp success = -EIO; 568470decc6SDave Kleikamp } 569470decc6SDave Kleikamp } 570470decc6SDave Kleikamp 571470decc6SDave Kleikamp return success; 572470decc6SDave Kleikamp 573470decc6SDave Kleikamp failed: 574470decc6SDave Kleikamp return err; 575470decc6SDave Kleikamp } 576470decc6SDave Kleikamp 577470decc6SDave Kleikamp 578470decc6SDave Kleikamp /* Scan a revoke record, marking all blocks mentioned as revoked. */ 579470decc6SDave Kleikamp 580470decc6SDave Kleikamp static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, 581470decc6SDave Kleikamp tid_t sequence, struct recovery_info *info) 582470decc6SDave Kleikamp { 583f7f4bccbSMingming Cao jbd2_journal_revoke_header_t *header; 584470decc6SDave Kleikamp int offset, max; 585*b517bea1SZach Brown int record_len = 4; 586470decc6SDave Kleikamp 587f7f4bccbSMingming Cao header = (jbd2_journal_revoke_header_t *) bh->b_data; 588f7f4bccbSMingming Cao offset = sizeof(jbd2_journal_revoke_header_t); 589470decc6SDave Kleikamp max = be32_to_cpu(header->r_count); 590470decc6SDave Kleikamp 591*b517bea1SZach Brown if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) 592*b517bea1SZach Brown record_len = 8; 593*b517bea1SZach Brown 594*b517bea1SZach Brown while (offset + record_len <= max) { 595470decc6SDave Kleikamp unsigned long blocknr; 596470decc6SDave Kleikamp int err; 597470decc6SDave Kleikamp 598*b517bea1SZach Brown if (record_len == 4) 599470decc6SDave Kleikamp blocknr = be32_to_cpu(* ((__be32 *) (bh->b_data+offset))); 600*b517bea1SZach Brown else 601*b517bea1SZach Brown blocknr = be64_to_cpu(* ((__be64 *) (bh->b_data+offset))); 602*b517bea1SZach Brown offset += record_len; 603f7f4bccbSMingming Cao err = jbd2_journal_set_revoke(journal, blocknr, sequence); 604470decc6SDave Kleikamp if (err) 605470decc6SDave Kleikamp return err; 606470decc6SDave Kleikamp ++info->nr_revokes; 607470decc6SDave Kleikamp } 608470decc6SDave Kleikamp return 0; 609470decc6SDave Kleikamp } 610