// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. */ #include <linux/module.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/completion.h> #include <linux/buffer_head.h> #include <linux/gfs2_ondisk.h> #include <linux/crc32.h> #include <linux/crc32c.h> #include <linux/ktime.h> #include "gfs2.h" #include "incore.h" #include "bmap.h" #include "glock.h" #include "glops.h" #include "log.h" #include "lops.h" #include "meta_io.h" #include "recovery.h" #include "super.h" #include "util.h" #include "dir.h" struct workqueue_struct *gfs2_recovery_wq; int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, struct buffer_head **bh) { … } int gfs2_revoke_add(struct gfs2_jdesc *jd, u64 blkno, unsigned int where) { … } int gfs2_revoke_check(struct gfs2_jdesc *jd, u64 blkno, unsigned int where) { … } void gfs2_revoke_clean(struct gfs2_jdesc *jd) { … } int __get_log_header(struct gfs2_sbd *sdp, const struct gfs2_log_header *lh, unsigned int blkno, struct gfs2_log_header_host *head) { … } /** * get_log_header - read the log header for a given segment * @jd: the journal * @blk: the block to look at * @head: the log header to return * * Read the log header for a given segement in a given journal. Do a few * sanity checks on it. * * Returns: 0 on success, * 1 if the header was invalid or incomplete, * errno on error */ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, struct gfs2_log_header_host *head) { … } /** * foreach_descriptor - go through the active part of the log * @jd: the journal * @start: the first log header in the active region * @end: the last log header (don't process the contents of this entry)) * @pass: iteration number (foreach_descriptor() is called in a for() loop) * * Call a given function once for every log descriptor in the active * portion of the log. * * Returns: errno */ static int foreach_descriptor(struct gfs2_jdesc *jd, u32 start, unsigned int end, int pass) { … } /** * clean_journal - mark a dirty journal as being clean * @jd: the journal * @head: the head journal to start from * * Returns: errno */ static void clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) { … } static void gfs2_recovery_done(struct gfs2_sbd *sdp, unsigned int jid, unsigned int message) { … } /** * update_statfs_inode - Update the master statfs inode or zero out the local * statfs inode for a given journal. * @jd: The journal * @head: If NULL, @inode is the local statfs inode and we need to zero it out. * Otherwise, it @head contains the statfs change info that needs to be * synced to the master statfs inode (pointed to by @inode). * @inode: statfs inode to update. */ static int update_statfs_inode(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head, struct inode *inode) { … } /** * recover_local_statfs - Update the master and local statfs changes for this * journal. * * Previously, statfs updates would be read in from the local statfs inode and * synced to the master statfs inode during recovery. * * We now use the statfs updates in the journal head to update the master statfs * inode instead of reading in from the local statfs inode. To preserve backward * compatibility with kernels that can't do this, we still need to keep the * local statfs inode up to date by writing changes to it. At some point in the * future, we can do away with the local statfs inodes altogether and keep the * statfs changes solely in the journal. * * @jd: the journal * @head: the journal head * * Returns: errno */ static void recover_local_statfs(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) { … } void gfs2_recover_func(struct work_struct *work) { … } int gfs2_recover_journal(struct gfs2_jdesc *jd, bool wait) { … }