// SPDX-License-Identifier: GPL-2.0+ /* * linux/fs/jbd2/recovery.c * * Written by Stephen C. Tweedie <[email protected]>, 1999 * * Copyright 1999-2000 Red Hat Software --- All Rights Reserved * * Journal recovery routines for the generic filesystem journaling code; * part of the ext2fs journaling system. */ #ifndef __KERNEL__ #include "jfs_user.h" #else #include <linux/time.h> #include <linux/fs.h> #include <linux/jbd2.h> #include <linux/errno.h> #include <linux/crc32.h> #include <linux/blkdev.h> #include <linux/string_choices.h> #endif /* * Maintain information about the progress of the recovery job, so that * the different passes can carry information between them. */ struct recovery_info { … }; static int do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass); static int scan_revoke_records(journal_t *, struct buffer_head *, tid_t, struct recovery_info *); #ifdef __KERNEL__ /* Release readahead buffers after use */ static void journal_brelse_array(struct buffer_head *b[], int n) { … } /* * When reading from the journal, we are going through the block device * layer directly and so there is no readahead being done for us. We * need to implement any readahead ourselves if we want it to happen at * all. Recovery is basically one long sequential read, so make sure we * do the IO in reasonably large chunks. * * This is not so critical that we need to be enormously clever about * the readahead size, though. 128K is a purely arbitrary, good-enough * fixed value. */ #define MAXBUF … static int do_readahead(journal_t *journal, unsigned int start) { … } #endif /* __KERNEL__ */ /* * Read a block from the journal */ static int jread(struct buffer_head **bhp, journal_t *journal, unsigned int offset) { … } static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf) { … } /* * Count the number of in-use tags in a journal descriptor block. */ static int count_tags(journal_t *journal, struct buffer_head *bh) { … } /* Make sure we wrap around the log correctly! */ #define wrap(journal, var) … static int fc_do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass) { … } /** * jbd2_journal_recover - recovers a on-disk journal * @journal: the journal to recover * * The primary function for recovering the log contents when mounting a * journaled device. * * Recovery is done in three passes. In the first pass, we look for the * end of the log. In the second, we assemble the list of revoke * blocks. In the third and final pass, we replay any un-revoked blocks * in the log. */ int jbd2_journal_recover(journal_t *journal) { … } /** * jbd2_journal_skip_recovery - Start journal and wipe exiting records * @journal: journal to startup * * Locate any valid recovery information from the journal and set up the * journal structures in memory to ignore it (presumably because the * caller has evidence that it is out of date). * This function doesn't appear to be exported.. * * We perform one pass over the journal to allow us to tell the user how * much recovery information is being erased, and to let us initialise * the journal transaction sequence numbers to the next unused ID. */ int jbd2_journal_skip_recovery(journal_t *journal) { … } static inline unsigned long long read_tag_block(journal_t *journal, journal_block_tag_t *tag) { … } /* * calc_chksums calculates the checksums for the blocks described in the * descriptor block. */ static int calc_chksums(journal_t *journal, struct buffer_head *bh, unsigned long *next_log_block, __u32 *crc32_sum) { … } static int jbd2_commit_block_csum_verify(journal_t *j, void *buf) { … } static bool jbd2_commit_block_csum_verify_partial(journal_t *j, void *buf) { … } static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag, journal_block_tag3_t *tag3, void *buf, __u32 sequence) { … } static int do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass) { … } /* Scan a revoke record, marking all blocks mentioned as revoked. */ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, tid_t sequence, struct recovery_info *info) { … }