This is an automated email from the git hooks/post-receive script.
andyp pushed a commit to branch andyp-fsck_cx in repository gfs2-utils.
commit 5f70beb3ef86f68a0fdc22d9e1adcec3612c0358 Author: Andrew Price anprice@redhat.com AuthorDate: Fri Jul 29 17:12:45 2022 +0100
fsck.gfs2: Pass the fsck_cx into the metawalk_fxns
This will allow data such as currently global variables and a separate set of resource groups to be passed in later.
Signed-off-by: Andrew Price anprice@redhat.com --- gfs2/fsck/afterpass1_common.c | 22 +++---- gfs2/fsck/afterpass1_common.h | 19 +++--- gfs2/fsck/fs_recovery.c | 29 +++++---- gfs2/fsck/fs_recovery.h | 4 +- gfs2/fsck/fsck.h | 5 +- gfs2/fsck/initialize.c | 23 +++---- gfs2/fsck/main.c | 2 +- gfs2/fsck/metawalk.c | 92 ++++++++++++++-------------- gfs2/fsck/metawalk.h | 44 +++++++------- gfs2/fsck/pass1.c | 137 +++++++++++++++++++++--------------------- gfs2/fsck/pass1b.c | 85 +++++++++++++------------- gfs2/fsck/pass2.c | 111 +++++++++++++++++----------------- gfs2/fsck/pass3.c | 8 +-- gfs2/fsck/pass4.c | 34 +++++------ gfs2/fsck/rgrepair.c | 12 ++-- gfs2/fsck/util.c | 2 +- gfs2/fsck/util.h | 2 +- 17 files changed, 315 insertions(+), 316 deletions(-)
diff --git a/gfs2/fsck/afterpass1_common.c b/gfs2/fsck/afterpass1_common.c index b41f216e..84e50f5b 100644 --- a/gfs2/fsck/afterpass1_common.c +++ b/gfs2/fsck/afterpass1_common.c @@ -109,7 +109,7 @@ static int delete_block_if_notdup(struct lgfs2_inode *ip, uint64_t block, return META_IS_GOOD; }
-static int remove_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int remove_dentry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, @@ -131,10 +131,10 @@ static int remove_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent,
}
-int remove_dentry_from_dir(struct lgfs2_sbd *sdp, uint64_t dir, - uint64_t dentryblock) +int remove_dentry_from_dir(struct fsck_cx *cx, uint64_t dir, uint64_t dentryblock) { struct metawalk_fxns remove_dentry_fxns = {0}; + struct lgfs2_sbd *sdp = cx->sdp; struct lgfs2_inode *ip; int q; int error; @@ -161,12 +161,12 @@ int remove_dentry_from_dir(struct lgfs2_sbd *sdp, uint64_t dir, } /* Need to run check_dir with a private var of dentryblock, * and fxns that remove that dentry if found */ - error = check_dir(sdp, ip, &remove_dentry_fxns); + error = check_dir(cx, ip, &remove_dentry_fxns); fsck_inode_put(&ip); return error; }
-int delete_metadata(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, +int delete_metadata(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -178,13 +178,13 @@ int delete_metadata(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int was_duplicate, private); }
-int delete_leaf(struct lgfs2_inode *ip, uint64_t block, void *private) +int delete_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private) { return delete_block_if_notdup(ip, block, NULL, _("leaf"), NULL, private); }
-int delete_data(struct lgfs2_inode *ip, uint64_t metablock, +int delete_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { @@ -223,21 +223,21 @@ static int del_eattr_generic(struct lgfs2_inode *ip, uint64_t block, return ret; }
-int delete_eattr_indir(struct lgfs2_inode *ip, uint64_t block, uint64_t parent, +int delete_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { return del_eattr_generic(ip, block, parent, bh, private, _("extended attribute")); }
-int delete_eattr_leaf(struct lgfs2_inode *ip, uint64_t block, uint64_t parent, +int delete_eattr_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { return del_eattr_generic(ip, block, parent, bh, private, _("indirect extended attribute")); }
-int delete_eattr_entry(struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh, +int delete_eattr_entry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, void *private) { @@ -277,7 +277,7 @@ int delete_eattr_entry(struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh return 0; }
-int delete_eattr_extentry(struct lgfs2_inode *ip, int i, __be64 *ea_data_ptr, +int delete_eattr_extentry(struct fsck_cx *cx, struct lgfs2_inode *ip, int i, __be64 *ea_data_ptr, struct lgfs2_buffer_head *leaf_bh, uint32_t tot_ealen, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, void *private) diff --git a/gfs2/fsck/afterpass1_common.h b/gfs2/fsck/afterpass1_common.h index 055816b4..4b0ab96e 100644 --- a/gfs2/fsck/afterpass1_common.h +++ b/gfs2/fsck/afterpass1_common.h @@ -4,28 +4,27 @@ #include "util.h" #include "metawalk.h"
-extern int delete_metadata(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, - int *was_duplicate, void *private); -extern int delete_leaf(struct lgfs2_inode *ip, uint64_t block, void *private); -extern int delete_data(struct lgfs2_inode *ip, uint64_t metablock, +extern int delete_metadata(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, + int h, int *is_valid, int *was_duplicate, void *private); +extern int delete_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private); +extern int delete_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr); -extern int delete_eattr_indir(struct lgfs2_inode *ip, uint64_t block, uint64_t parent, +extern int delete_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private); -extern int delete_eattr_leaf(struct lgfs2_inode *ip, uint64_t block, uint64_t parent, +extern int delete_eattr_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private); -extern int delete_eattr_entry(struct lgfs2_inode *ip, +extern int delete_eattr_entry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, void *private); -extern int delete_eattr_extentry(struct lgfs2_inode *ip, int i, +extern int delete_eattr_extentry(struct fsck_cx *cx, struct lgfs2_inode *ip, int i, __be64 *ea_data_ptr, struct lgfs2_buffer_head *leaf_bh, uint32_t tot_ealen, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, void *private); -extern int remove_dentry_from_dir(struct lgfs2_sbd *sdp, uint64_t dir, - uint64_t dentryblock); +extern int remove_dentry_from_dir(struct fsck_cx *cx, uint64_t dir, uint64_t dentryblock); #endif diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c index 97c42e4d..607ef9c2 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -620,7 +620,7 @@ static int rangecheck_jblock(struct lgfs2_inode *ip, uint64_t block) return META_IS_GOOD; }
-static int rangecheck_jmeta(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int rangecheck_jmeta(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -648,7 +648,7 @@ static int rangecheck_jmeta(struct iptr iptr, struct lgfs2_buffer_head **bh, int return rc; }
-static int rangecheck_jdata(struct lgfs2_inode *ip, uint64_t metablock, +static int rangecheck_jdata(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { @@ -675,11 +675,15 @@ static struct metawalk_fxns rangecheck_journal = { * * Returns: 0 on success, -1 on failure */ -int replay_journals(struct lgfs2_sbd *sdp, int preen, int force_check, +int replay_journals(struct fsck_cx *cx, int preen, int force_check, int *clean_journals) { + struct lgfs2_sbd *sdp = cx->sdp; + int dirty_journals = 0; + int gave_msg = 0; + int error = 0; + int clean = 0; int i; - int clean = 0, dirty_journals = 0, error = 0, gave_msg = 0;
*clean_journals = 0;
@@ -687,7 +691,7 @@ int replay_journals(struct lgfs2_sbd *sdp, int preen, int force_check,
for(i = 0; i < sdp->md.journals; i++) { if (sdp->md.journal[i]) { - error = check_metatree(sdp->md.journal[i], + error = check_metatree(cx, sdp->md.journal[i], &rangecheck_journal); if (error) /* Don't use fsck_inode_put here because it's a @@ -808,7 +812,7 @@ static void bad_journalname(const char *filename, int len) * This function makes sure the directory entries of the jindex are valid. * If they're not '.' or '..' they better have the form journalXXX. */ -static int check_jindex_dent(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int check_jindex_dent(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, void *priv) @@ -869,14 +873,9 @@ int build_jindex(struct lgfs2_sbd *sdp) return 0; }
-/** - * init_jindex - read in the rindex file - */ -int init_jindex(struct lgfs2_sbd *sdp, int allow_ji_rebuild) +int init_jindex(struct fsck_cx *cx, int allow_ji_rebuild) { - /******************************************************************* - ****************** Fill in journal information ****************** - *******************************************************************/ + struct lgfs2_sbd *sdp = cx->sdp;
log_debug(_("Validating the journal index.\n")); /* rgrepair requires the journals be read in in order to distinguish @@ -916,10 +915,10 @@ int init_jindex(struct lgfs2_sbd *sdp, int allow_ji_rebuild)
log_debug(_("Checking the integrity of the journal index.\n")); if (sdp->md.jiinode->i_flags & GFS2_DIF_EXHASH) - error = check_leaf_blks(sdp->md.jiinode, + error = check_leaf_blks(cx, sdp->md.jiinode, &jindex_check_fxns); else - error = check_linear_dir(sdp->md.jiinode, + error = check_linear_dir(cx, sdp->md.jiinode, sdp->md.jiinode->i_bh, &jindex_check_fxns); if (error) { diff --git a/gfs2/fsck/fs_recovery.h b/gfs2/fsck/fs_recovery.h index 0d5a785d..51d632ee 100644 --- a/gfs2/fsck/fs_recovery.h +++ b/gfs2/fsck/fs_recovery.h @@ -3,12 +3,12 @@
#include "libgfs2.h"
-extern int replay_journals(struct lgfs2_sbd *sdp, int preen, int force_check, +extern int replay_journals(struct fsck_cx *cx, int preen, int force_check, int *clean_journals); extern int preen_is_safe(struct lgfs2_sbd *sdp, int preen, int force_check);
extern int ji_update(struct lgfs2_sbd *sdp); extern int build_jindex(struct lgfs2_sbd *sdp); -extern int init_jindex(struct lgfs2_sbd *sdp, int allow_ji_rebuild); +extern int init_jindex(struct fsck_cx *cx, int allow_ji_rebuild); #endif /* __FS_RECOVERY_H__ */
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index d4be11e4..382abfab 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -118,8 +118,7 @@ extern struct lgfs2_inode *fsck_inode_get(struct lgfs2_sbd *sdp, struct lgfs2_buffer_head *bh); extern void fsck_inode_put(struct lgfs2_inode **ip);
-extern int initialize(struct lgfs2_sbd *sdp, int force_check, int preen, - int *all_clean); +extern int initialize(struct fsck_cx *cx, int force_check, int preen, int *all_clean); extern void destroy(struct lgfs2_sbd *sdp); extern int pass1(struct fsck_cx *cx); extern int pass1b(struct fsck_cx *cx); @@ -128,7 +127,7 @@ extern int pass2(struct fsck_cx *cx); extern int pass3(struct fsck_cx *cx); extern int pass4(struct fsck_cx *cx); extern int pass5(struct fsck_cx *cx, struct gfs2_bmap *bl); -extern int rindex_repair(struct lgfs2_sbd *sdp, int trust_lvl, int *ok); +extern int rindex_repair(struct fsck_cx *cx, int trust_lvl, int *ok); extern int fsck_query(const char *format, ...) __attribute__((format(printf,1,2))); extern struct dir_info *dirtree_find(uint64_t block); diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index eade7f3c..9d771a70 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -697,7 +697,7 @@ static int read_rgrps(struct lgfs2_sbd *sdp, uint64_t expected) return -1; }
-static int fetch_rgrps_level(struct lgfs2_sbd *sdp, enum rgindex_trust_level lvl, uint64_t *count, int *ok) +static int fetch_rgrps_level(struct fsck_cx *cx, enum rgindex_trust_level lvl, uint64_t *count, int *ok) { int ret = 1;
@@ -718,13 +718,13 @@ static int fetch_rgrps_level(struct lgfs2_sbd *sdp, enum rgindex_trust_level lvl
log_notice(_("Level %d resource group check: %s.\n"), lvl + 1, level_desc[lvl]);
- if (rindex_repair(sdp, lvl, ok) != 0) + if (rindex_repair(cx, lvl, ok) != 0) goto fail;
- if (lgfs2_rindex_read(sdp, count, ok) != 0 || !*ok) + if (lgfs2_rindex_read(cx->sdp, count, ok) != 0 || !*ok) goto fail;
- ret = read_rgrps(sdp, *count); + ret = read_rgrps(cx->sdp, *count); if (ret != 0) goto fail;
@@ -742,7 +742,7 @@ fail: /** * fetch_rgrps - fetch the resource groups from disk, and check their integrity */ -static int fetch_rgrps(struct lgfs2_sbd *sdp) +static int fetch_rgrps(struct fsck_cx *cx) { enum rgindex_trust_level trust_lvl; uint64_t rgcount; @@ -752,7 +752,7 @@ static int fetch_rgrps(struct lgfs2_sbd *sdp) for (trust_lvl = BLIND_FAITH; trust_lvl <= INDIGNATION; trust_lvl++) { int ret = 0;
- ret = fetch_rgrps_level(sdp, trust_lvl, &rgcount, &ok); + ret = fetch_rgrps_level(cx, trust_lvl, &rgcount, &ok); if (ret == 0) break; if (fsck_abort) @@ -765,7 +765,7 @@ static int fetch_rgrps(struct lgfs2_sbd *sdp) } log_info( _("%"PRIu64" resource groups found.\n"), rgcount);
- check_rgrps_integrity(sdp); + check_rgrps_integrity(cx->sdp); return 0; }
@@ -1544,9 +1544,10 @@ static int init_rindex(struct lgfs2_sbd *sdp) * initialize - initialize superblock pointer * */ -int initialize(struct lgfs2_sbd *sdp, int force_check, int preen, +int initialize(struct fsck_cx *cx, int force_check, int preen, int *all_clean) { + struct lgfs2_sbd *sdp = cx->sdp; int clean_journals = 0, open_flag; int err;
@@ -1638,20 +1639,20 @@ int initialize(struct lgfs2_sbd *sdp, int force_check, int preen, if (init_rindex(sdp)) return FSCK_ERROR;
- if (fetch_rgrps(sdp)) + if (fetch_rgrps(cx)) return FSCK_ERROR;
/* We need to read in jindex in order to replay the journals. If there's an error, we may proceed and let init_system_inodes try to rebuild it. */ - if (init_jindex(sdp, 1) == 0) { + if (init_jindex(cx, 1) == 0) { /* If GFS, rebuild the journals. If GFS2, replay them. We don't have the smarts to replay GFS1 journals (neither did gfs_fsck). */ if (sdp->gfs1) { if (reconstruct_journals(sdp)) return FSCK_ERROR; - } else if (replay_journals(sdp, preen, force_check, + } else if (replay_journals(cx, preen, force_check, &clean_journals)) { if (!opts.no && preen_is_safe(sdp, preen, force_check)) block_mounters(sdp, 0); diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 7eb45c63..fff0d32d 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -330,7 +330,7 @@ int main(int argc, char **argv) exit(error); setbuf(stdout, NULL); log_notice( _("Initializing fsck\n")); - if ((error = initialize(&sb, force_check, preen, &all_clean))) + if ((error = initialize(&cx, force_check, preen, &all_clean))) exit(error);
if (!force_check && all_clean && preen) { diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index 9c8d857b..36f4abcb 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -381,7 +381,7 @@ static void dirblk_truncate(struct lgfs2_inode *ip, struct gfs2_dirent *fixb, * returns: 0 - good block or it was repaired to be good * -1 - error occurred */ -static int check_entries(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, +static int check_entries(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, int type, uint32_t *count, int lindex, struct metawalk_fxns *pass) { @@ -477,7 +477,7 @@ static int check_entries(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, /* Mark dirent buffer as modified */ first = 0; } else { - error = pass->check_dentry(ip, dent, prev, bh, + error = pass->check_dentry(cx, ip, dent, prev, bh, filename, count, &lindex, pass->private); @@ -511,7 +511,7 @@ static int check_entries(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, * Reads in the leaf block * Leaves the buffer around for further analysis (caller must lgfs2_brelse) */ -int check_leaf(struct lgfs2_inode *ip, int lindex, struct metawalk_fxns *pass, +int check_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, int lindex, struct metawalk_fxns *pass, uint64_t *leaf_no, struct lgfs2_leaf *leaf, int *ref_count) { int error = 0, fix; @@ -540,10 +540,10 @@ int check_leaf(struct lgfs2_inode *ip, int lindex, struct metawalk_fxns *pass, goto bad_leaf; } if (pass->check_leaf_depth) - error = pass->check_leaf_depth(ip, *leaf_no, *ref_count, lbh); + error = pass->check_leaf_depth(cx, ip, *leaf_no, *ref_count, lbh);
if (error >= 0 && pass->check_leaf) { - error = pass->check_leaf(ip, *leaf_no, pass->private); + error = pass->check_leaf(cx, ip, *leaf_no, pass->private); if (error == -EEXIST) { log_info(_("Previous reference to leaf %"PRIu64" (0x%"PRIx64") " "has already checked it; skipping.\n"), @@ -578,7 +578,7 @@ int check_leaf(struct lgfs2_inode *ip, int lindex, struct metawalk_fxns *pass, }
if (pass->check_dentry && is_dir(ip, sdp->gfs1)) { - error = check_entries(ip, lbh, DIR_EXHASH, &count, lindex, + error = check_entries(cx, ip, lbh, DIR_EXHASH, &count, lindex, pass);
if (skip_this_pass || fsck_abort) @@ -631,7 +631,7 @@ bad_leaf: lgfs2_brelse(lbh); if (pass->repair_leaf) { /* The leaf we read in is bad so we need to repair it. */ - fix = pass->repair_leaf(ip, leaf_no, lindex, *ref_count, msg); + fix = pass->repair_leaf(cx, ip, leaf_no, lindex, *ref_count, msg); if (fix < 0) return fix;
@@ -678,7 +678,7 @@ static void dir_leaf_reada(struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize) }
/* Checks exhash directory entries */ -int check_leaf_blks(struct lgfs2_inode *ip, struct metawalk_fxns *pass) +int check_leaf_blks(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass) { int error = 0; unsigned hsize = (1 << ip->i_depth); @@ -708,7 +708,7 @@ int check_leaf_blks(struct lgfs2_inode *ip, struct metawalk_fxns *pass) dir_leaf_reada(ip, tbl, hsize);
if (pass->check_hash_tbl) { - error = pass->check_hash_tbl(ip, tbl, hsize, pass->private); + error = pass->check_hash_tbl(cx, ip, tbl, hsize, pass->private); if (error < 0) { free(tbl); (void)posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL); @@ -793,7 +793,7 @@ int check_leaf_blks(struct lgfs2_inode *ip, struct metawalk_fxns *pass) (void)posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL); return 0; } - error = check_leaf(ip, lindex, pass, &leaf_no, &leaf, + error = check_leaf(cx, ip, lindex, pass, &leaf_no, &leaf, &ref_count); if (ref_count != orig_ref_count) { log_debug(_("Ref count of leaf 0x%"PRIx64 @@ -836,7 +836,7 @@ int check_leaf_blks(struct lgfs2_inode *ip, struct metawalk_fxns *pass) return 0; }
-static int check_eattr_entries(struct lgfs2_inode *ip, +static int check_eattr_entries(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, struct metawalk_fxns *pass) { @@ -856,7 +856,7 @@ static int check_eattr_entries(struct lgfs2_inode *ip, if (ea_hdr->ea_type == GFS2_EATYPE_UNUSED) error = 0; else - error = pass->check_eattr_entry(ip, bh, ea_hdr, + error = pass->check_eattr_entry(cx, ip, bh, ea_hdr, ea_hdr_prev, pass->private); if (error < 0) { @@ -880,7 +880,7 @@ static int check_eattr_entries(struct lgfs2_inode *ip, ** reuse........... */
for(i = 0; i < ea_hdr->ea_num_ptrs; i++){ - err = pass->check_eattr_extentry(ip, i, + err = pass->check_eattr_extentry(cx, ip, i, ea_data_ptr, bh, tot_ealen, ea_hdr, ea_hdr_prev, pass->private); @@ -912,7 +912,7 @@ static int check_eattr_entries(struct lgfs2_inode *ip, * * Returns: 0 on success, 1 if removal is needed, -1 on error */ -static int check_leaf_eattr(struct lgfs2_inode *ip, uint64_t block, +static int check_leaf_eattr(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct metawalk_fxns *pass) { struct lgfs2_buffer_head *bh = NULL; @@ -924,7 +924,7 @@ static int check_leaf_eattr(struct lgfs2_inode *ip, uint64_t block, "inode #%"PRIu64" (0x%"PRIx64").\n"), block, block, ip->i_num.in_addr, ip->i_num.in_addr);
- error = pass->check_eattr_leaf(ip, block, parent, &bh, + error = pass->check_eattr_leaf(cx, ip, block, parent, &bh, pass->private); if (error < 0) { stack; @@ -936,7 +936,7 @@ static int check_leaf_eattr(struct lgfs2_inode *ip, uint64_t block, return 1; } if (bh) { - error = check_eattr_entries(ip, bh, pass); + error = check_eattr_entries(cx, ip, bh, pass); lgfs2_brelse(bh); } return error; @@ -952,7 +952,7 @@ static int check_leaf_eattr(struct lgfs2_inode *ip, uint64_t block, * * Returns: 0 on success -1 on error */ -static int check_indirect_eattr(struct lgfs2_inode *ip, uint64_t indirect, +static int check_indirect_eattr(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t indirect, struct lgfs2_buffer_head *indirect_buf, struct metawalk_fxns *pass) { @@ -971,7 +971,7 @@ static int check_indirect_eattr(struct lgfs2_inode *ip, uint64_t indirect, while (*ea_leaf_ptr && (ea_leaf_ptr < end)){ block = be64_to_cpu(*ea_leaf_ptr); leaf_pointers++; - err = check_leaf_eattr(ip, block, indirect, pass); + err = check_leaf_eattr(cx, ip, block, indirect, pass); if (err) { error = err; log_err(_("Error detected in leaf block %"PRIu64" (0x%"PRIx64") " @@ -996,7 +996,7 @@ static int check_indirect_eattr(struct lgfs2_inode *ip, uint64_t indirect, if (leaf_pointers == 1 && leaf_pointer_errors == 1) { first_ea_is_bad = 1; if (pass->finish_eattr_indir) - pass->finish_eattr_indir(ip, leaf_pointers, + pass->finish_eattr_indir(cx, ip, leaf_pointers, leaf_pointer_errors, pass->private); } else if (leaf_pointer_errors) { @@ -1017,13 +1017,13 @@ static int check_indirect_eattr(struct lgfs2_inode *ip, uint64_t indirect, ip->i_eattr = di_eattr_save; if (pass->finish_eattr_indir) { if (!first_ea_is_bad) { - pass->finish_eattr_indir(ip, leaf_pointers, + pass->finish_eattr_indir(cx, ip, leaf_pointers, leaf_pointer_errors, pass->private); } if (pass->delete_block && leaf_pointer_errors && leaf_pointer_errors == leaf_pointers) { - pass->delete_block(ip, indirect, NULL, "leaf", NULL); + pass->delete_block(cx, ip, indirect, NULL, "leaf", NULL); error = 1; } } @@ -1037,7 +1037,7 @@ static int check_indirect_eattr(struct lgfs2_inode *ip, uint64_t indirect, * * Returns: 0 on success, -1 on error */ -int check_inode_eattr(struct lgfs2_inode *ip, struct metawalk_fxns *pass) +int check_inode_eattr(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass) { int error = 0; struct lgfs2_buffer_head *indirect_buf = NULL; @@ -1052,10 +1052,10 @@ int check_inode_eattr(struct lgfs2_inode *ip, struct metawalk_fxns *pass) log_debug(_("Checking EA indirect block #%"PRIu64" (0x%"PRIx64") for " "inode #%"PRIu64" (0x%"PRIx64")..\n"), ip->i_eattr, ip->i_eattr, ip->i_num.in_addr, ip->i_num.in_addr); - error = pass->check_eattr_indir(ip, ip->i_eattr, ip->i_num.in_addr, + error = pass->check_eattr_indir(cx, ip, ip->i_eattr, ip->i_num.in_addr, &indirect_buf, pass->private); if (!error) { - error = check_indirect_eattr(ip, ip->i_eattr, + error = check_indirect_eattr(cx, ip, ip->i_eattr, indirect_buf, pass); if (error) stack; @@ -1064,7 +1064,7 @@ int check_inode_eattr(struct lgfs2_inode *ip, struct metawalk_fxns *pass) lgfs2_brelse(indirect_buf); return error; } - error = check_leaf_eattr(ip, ip->i_eattr, ip->i_num.in_addr, pass); + error = check_leaf_eattr(cx, ip, ip->i_eattr, ip->i_num.in_addr, pass); if (error) stack;
@@ -1149,7 +1149,7 @@ static void file_ra(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, extlen * sdp->sd_bsize, POSIX_FADV_WILLNEED); }
-static int do_check_metalist(struct iptr iptr, int height, struct lgfs2_buffer_head **bhp, +static int do_check_metalist(struct fsck_cx *cx, struct iptr iptr, int height, struct lgfs2_buffer_head **bhp, struct metawalk_fxns *pass) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -1161,7 +1161,7 @@ static int do_check_metalist(struct iptr iptr, int height, struct lgfs2_buffer_h if (pass->check_metalist == NULL) return 0;
- error = pass->check_metalist(iptr, bhp, height, &is_valid, + error = pass->check_metalist(cx, iptr, bhp, height, &is_valid, &was_duplicate, pass->private); if (error == META_ERROR) { stack; @@ -1207,7 +1207,7 @@ static int do_check_metalist(struct iptr iptr, int height, struct lgfs2_buffer_h * @ip: * @mlp: */ -static int build_and_check_metalist(struct lgfs2_inode *ip, osi_list_t *mlp, +static int build_and_check_metalist(struct fsck_cx *cx, struct lgfs2_inode *ip, osi_list_t *mlp, struct metawalk_fxns *pass) { uint32_t height = ip->i_height; @@ -1277,7 +1277,7 @@ static int build_and_check_metalist(struct lgfs2_inode *ip, osi_list_t *mlp, if (!iptr_block(iptr)) continue;
- error = do_check_metalist(iptr, h, &nbh, pass); + error = do_check_metalist(cx, iptr, h, &nbh, pass); if (error == META_ERROR || error == META_SKIP_FURTHER) goto error_undo; if (error == META_SKIP_ONE) @@ -1304,7 +1304,7 @@ error_undo: /* undo what we've done so far for this block */ if (block == 0) continue;
- pass->undo_check_meta(ip, block, h, pass->private); + pass->undo_check_meta(cx, ip, block, h, pass->private); } return error; } @@ -1380,7 +1380,7 @@ static void report_data_error(uint64_t metablock, int offset, uint64_t block, * 1 if errors were found and corrected * 2 (ENOENT) is there were too many bad pointers */ -static int metawalk_check_data(struct lgfs2_inode *ip, struct metawalk_fxns *pass, +static int metawalk_check_data(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass, struct lgfs2_buffer_head *bh, unsigned int height, uint64_t *blks_checked, struct error_block *error_blk) { @@ -1406,7 +1406,7 @@ static int metawalk_check_data(struct lgfs2_inode *ip, struct metawalk_fxns *pas would defeat the rangecheck_block related functions in pass1. Therefore the individual check_data functions should do a range check. */ - rc = pass->check_data(ip, metablock, block, pass->private, + rc = pass->check_data(cx, ip, metablock, block, pass->private, bh, ptr); if (rc && (!error || (rc < error))) { report_data_error(metablock, (char *)ptr - bh->b_data, block, error_blk, rc, error); @@ -1448,7 +1448,7 @@ static int report_undo_data_error(uint64_t metablock, int offset, uint64_t block return 0; }
-static int undo_check_data(struct lgfs2_inode *ip, struct metawalk_fxns *pass, +static int undo_check_data(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass, struct lgfs2_buffer_head *bh, unsigned int height, struct error_block *error_blk, int error) { @@ -1471,7 +1471,7 @@ static int undo_check_data(struct lgfs2_inode *ip, struct metawalk_fxns *pass, if (report_undo_data_error(metablock, (char *)ptr - bh->b_data, block, error_blk, &found_error_blk, error)) return 1; - rc = pass->undo_check_data(ip, block, pass->private); + rc = pass->undo_check_data(cx, ip, block, pass->private); if (rc < 0) return rc; } @@ -1491,7 +1491,7 @@ static unsigned int should_check(struct lgfs2_buffer_head *bh, unsigned int heig * @pass: structure passed in from caller to determine the sub-functions * */ -int check_metatree(struct lgfs2_inode *ip, struct metawalk_fxns *pass) +int check_metatree(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass) { unsigned int height = ip->i_height; osi_list_t *metalist = alloca((height + 1) * sizeof(*metalist)); @@ -1512,7 +1512,7 @@ int check_metatree(struct lgfs2_inode *ip, struct metawalk_fxns *pass) osi_list_init(&metalist[i]);
/* create and check the metadata list for each height */ - error = build_and_check_metalist(ip, metalist, pass); + error = build_and_check_metalist(cx, ip, metalist, pass); if (error) { stack; goto undo_metalist; @@ -1526,7 +1526,7 @@ int check_metatree(struct lgfs2_inode *ip, struct metawalk_fxns *pass) if (!(ip->i_flags & GFS2_DIF_EXHASH)) goto out; /* check validity of leaf blocks and leaf chains */ - error = check_leaf_blks(ip, pass); + error = check_leaf_blks(cx, ip, pass); if (error) goto undo_metalist; goto out; @@ -1547,10 +1547,10 @@ int check_metatree(struct lgfs2_inode *ip, struct metawalk_fxns *pass) continue;
if (pass->check_data) - error = metawalk_check_data(ip, pass, bh, height, + error = metawalk_check_data(cx, ip, pass, bh, height, &blks_checked, &error_blk); if (pass->big_file_msg && ip->i_blocks > COMFORTABLE_BLKS) - pass->big_file_msg(ip, blks_checked); + pass->big_file_msg(cx, ip, blks_checked); } if (pass->big_file_msg && ip->i_blocks > COMFORTABLE_BLKS) { log_notice( _("\rLarge file at %"PRIu64" (0x%"PRIx64") - 100 percent " @@ -1581,14 +1581,14 @@ undo_metalist: log_err(_("Undoing metadata work for block %"PRIu64" (0x%"PRIx64")\n"), bh->b_blocknr, bh->b_blocknr); if (i) - rc = pass->undo_check_meta(ip, bh->b_blocknr, + rc = pass->undo_check_meta(cx, ip, bh->b_blocknr, i, pass->private); else rc = 0; if (metadata_clean && rc == 0 && i == height - 1 && !hit_error_blk) { if (should_check(bh, height)) { - rc = undo_check_data(ip, pass, + rc = undo_check_data(cx, ip, pass, bh, height, &error_blk, @@ -1624,13 +1624,13 @@ out: }
/* Checks stuffed inode directories */ -int check_linear_dir(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, +int check_linear_dir(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, struct metawalk_fxns *pass) { int error = 0; uint32_t count = 0;
- error = check_entries(ip, bh, DIR_LINEAR, &count, 0, pass); + error = check_entries(cx, ip, bh, DIR_LINEAR, &count, 0, pass); if (error < 0) { stack; return -1; @@ -1639,14 +1639,14 @@ int check_linear_dir(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, return error; }
-int check_dir(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip, struct metawalk_fxns *pass) +int check_dir(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass) { int error = 0;
if (ip->i_flags & GFS2_DIF_EXHASH) - error = check_leaf_blks(ip, pass); + error = check_leaf_blks(cx, ip, pass); else - error = check_linear_dir(ip, ip->i_bh, pass); + error = check_linear_dir(cx, ip, ip->i_bh, pass);
if (error < 0) stack; diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h index eeff431d..0934c71c 100644 --- a/gfs2/fsck/metawalk.h +++ b/gfs2/fsck/metawalk.h @@ -8,15 +8,15 @@
struct metawalk_fxns;
-extern int check_inode_eattr(struct lgfs2_inode *ip, +extern int check_inode_eattr(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass); -extern int check_metatree(struct lgfs2_inode *ip, struct metawalk_fxns *pass); -extern int check_leaf_blks(struct lgfs2_inode *ip, struct metawalk_fxns *pass); -extern int check_dir(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip, +extern int check_metatree(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass); +extern int check_leaf_blks(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass); +extern int check_dir(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass); -extern int check_linear_dir(struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, +extern int check_linear_dir(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *bh, struct metawalk_fxns *pass); -extern int check_leaf(struct lgfs2_inode *ip, int lindex, +extern int check_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, int lindex, struct metawalk_fxns *pass, uint64_t *leaf_no, struct lgfs2_leaf *leaf, int *ref_count); extern int _fsck_bitmap_set(struct lgfs2_inode *ip, uint64_t bblock, @@ -72,9 +72,9 @@ struct metawalk_fxns { void *private; int invalid_meta_is_fatal; int readahead; - int (*check_leaf_depth) (struct lgfs2_inode *ip, uint64_t leaf_no, + int (*check_leaf_depth) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t leaf_no, int ref_count, struct lgfs2_buffer_head *lbh); - int (*check_leaf) (struct lgfs2_inode *ip, uint64_t block, + int (*check_leaf) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private); /* parameters to the check_metalist sub-functions: iptr: reference to the inode and its indirect pointer that we're analyzing @@ -90,48 +90,48 @@ struct metawalk_fxns { returns: 0 - everything is good, but there may be duplicates 1 - skip further processing */ - int (*check_metalist) (struct iptr iptr, + int (*check_metalist) (struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private); - int (*check_data) (struct lgfs2_inode *ip, uint64_t metablock, + int (*check_data) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr); - int (*check_eattr_indir) (struct lgfs2_inode *ip, uint64_t block, + int (*check_eattr_indir) (struct fsck_cx *, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private); - int (*check_eattr_leaf) (struct lgfs2_inode *ip, uint64_t block, + int (*check_eattr_leaf) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private); - int (*check_dentry) (struct lgfs2_inode *ip, struct gfs2_dirent *de, + int (*check_dentry) (struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *de, struct gfs2_dirent *prev, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, void *private); - int (*check_eattr_entry) (struct lgfs2_inode *ip, + int (*check_eattr_entry) (struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, void *private); - int (*check_eattr_extentry) (struct lgfs2_inode *ip, int i, + int (*check_eattr_extentry) (struct fsck_cx *cx, struct lgfs2_inode *ip, int i, __be64 *ea_data_ptr, struct lgfs2_buffer_head *leaf_bh, uint32_t tot_ealen, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, void *private); - int (*finish_eattr_indir) (struct lgfs2_inode *ip, int leaf_pointers, + int (*finish_eattr_indir) (struct fsck_cx *cx, struct lgfs2_inode *ip, int leaf_pointers, int leaf_pointer_errors, void *private); - void (*big_file_msg) (struct lgfs2_inode *ip, uint64_t blks_checked); - int (*check_hash_tbl) (struct lgfs2_inode *ip, __be64 *tbl, + void (*big_file_msg) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t blks_checked); + int (*check_hash_tbl) (struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, void *private); - int (*repair_leaf) (struct lgfs2_inode *ip, uint64_t *leaf_no, + int (*repair_leaf) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t *leaf_no, int lindex, int ref_count, const char *msg); - int (*undo_check_meta) (struct lgfs2_inode *ip, uint64_t block, + int (*undo_check_meta) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, int h, void *private); - int (*undo_check_data) (struct lgfs2_inode *ip, uint64_t block, + int (*undo_check_data) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private); - int (*delete_block) (struct lgfs2_inode *ip, uint64_t block, + int (*delete_block) (struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, struct lgfs2_buffer_head **bh, const char *btype, void *private); }; diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index a7dc442e..44199ac6 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -80,7 +80,7 @@ static int _fsck_blockmap_set(struct lgfs2_inode *ip, uint64_t bblock, /** * p1_delete_block - delete a block associated with an inode */ -static int p1_delete_block(struct lgfs2_inode *ip, uint64_t block, +static int p1_delete_block(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, struct lgfs2_buffer_head **bh, const char *btype, void *private) { @@ -93,7 +93,7 @@ static int p1_delete_block(struct lgfs2_inode *ip, uint64_t block,
/* This is a pass1-specific leaf repair. Since we are not allowed to do * block allocations, we do what we can. */ -static int p1_repair_leaf(struct lgfs2_inode *ip, uint64_t *leaf_no, +static int p1_repair_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t *leaf_no, int lindex, int ref_count, const char *msg) { uint64_t *cpyptr; @@ -138,7 +138,7 @@ out: * marked "in use" by the bitmap. You don't want root's indirect blocks * deleted, do you? Or worse, reused for lost+found. */ -static int resuscitate_metalist(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int resuscitate_metalist(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct block_count *bc = (struct block_count *)private; @@ -174,7 +174,7 @@ static int resuscitate_metalist(struct iptr iptr, struct lgfs2_buffer_head **bh, * This function makes sure directory entries in system directories are * kept alive. You don't want journal0 deleted from jindex, do you? */ -static int resuscitate_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int resuscitate_dentry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, void *priv) @@ -221,7 +221,7 @@ static struct metawalk_fxns sysdir_fxns = { .delete_block = p1_delete_block, };
-static int p1_check_leaf(struct lgfs2_inode *ip, uint64_t block, void *private) +static int p1_check_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private) { struct block_count *bc = (struct block_count *) private; int q; @@ -250,7 +250,7 @@ static int p1_check_leaf(struct lgfs2_inode *ip, uint64_t block, void *private) return 0; }
-static int p1_check_metalist(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int p1_check_metalist(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct block_count *bc = (struct block_count *)private; @@ -390,13 +390,13 @@ static int undo_reference(struct lgfs2_inode *ip, uint64_t block, int meta, return 0; }
-static int p1_undo_check_metalist(struct lgfs2_inode *ip, uint64_t block, +static int p1_undo_check_metalist(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, int h, void *private) { return undo_reference(ip, block, 1, private); }
-static int p1_undo_check_data(struct lgfs2_inode *ip, uint64_t block, +static int p1_undo_check_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private) { return undo_reference(ip, block, 0, private); @@ -444,7 +444,7 @@ out: return error; }
-static int p1_check_data(struct lgfs2_inode *ip, uint64_t metablock, +static int p1_check_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bbh, __be64 *ptr) { @@ -568,7 +568,7 @@ static int ask_remove_inode_eattr(struct lgfs2_inode *ip, return 0; }
-static int undo_eattr_indir_or_leaf(struct lgfs2_inode *ip, uint64_t block, +static int undo_eattr_indir_or_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) @@ -613,7 +613,7 @@ static void complain_eas(struct lgfs2_inode *ip, uint64_t block, log_err(_(" at block #%"PRIu64" (0x%"PRIx64").\n"), block, block); }
-static int p1_check_eattr_indir(struct lgfs2_inode *ip, uint64_t indirect, +static int p1_check_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t indirect, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { @@ -670,7 +670,7 @@ static int p1_check_eattr_indir(struct lgfs2_inode *ip, uint64_t indirect, return ret; }
-static int p1_finish_eattr_indir(struct lgfs2_inode *ip, int leaf_pointers, +static int p1_finish_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, int leaf_pointers, int leaf_pointer_errors, void *private) { struct block_count *bc = (struct block_count *) private; @@ -761,7 +761,7 @@ static int check_ealeaf_block(struct lgfs2_inode *ip, uint64_t block, int btype, * * Returns: 0 if correct[able], -1 if removal is needed */ -static int p1_check_extended_leaf_eattr(struct lgfs2_inode *ip, int i, +static int p1_check_extended_leaf_eattr(struct fsck_cx *cx, struct lgfs2_inode *ip, int i, __be64 *data_ptr, struct lgfs2_buffer_head *leaf_bh, uint32_t tot_ealen, @@ -812,7 +812,7 @@ static int p1_check_extended_leaf_eattr(struct lgfs2_inode *ip, int i, return error; }
-static int p1_check_eattr_leaf(struct lgfs2_inode *ip, uint64_t block, +static int p1_check_eattr_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { @@ -869,7 +869,7 @@ static int eatype_max(unsigned fs_format) return max; }
-static int p1_check_eattr_entries(struct lgfs2_inode *ip, +static int p1_check_eattr_entries(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, @@ -991,7 +991,7 @@ static int rangecheck_block(struct lgfs2_inode *ip, uint64_t block, return META_IS_GOOD; }
-static int rangecheck_metadata(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int rangecheck_metadata(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -1002,27 +1002,27 @@ static int rangecheck_metadata(struct iptr iptr, struct lgfs2_buffer_head **bh, return rangecheck_block(ip, block, bh, BTYPE_META, private); }
-static int rangecheck_leaf(struct lgfs2_inode *ip, uint64_t block, +static int rangecheck_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private) { return rangecheck_block(ip, block, NULL, BTYPE_LEAF, private); }
-static int rangecheck_data(struct lgfs2_inode *ip, uint64_t metablock, +static int rangecheck_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { return rangecheck_block(ip, block, NULL, BTYPE_DATA, private); }
-static int rangecheck_eattr_indir(struct lgfs2_inode *ip, uint64_t block, +static int rangecheck_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { return rangecheck_block(ip, block, NULL, BTYPE_IEATTR, private); }
-static int rangecheck_eattr_leaf(struct lgfs2_inode *ip, uint64_t block, +static int rangecheck_eattr_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { @@ -1097,7 +1097,7 @@ static int set_ip_blockmap(struct lgfs2_inode *ip) return 0; }
-static int alloc_metalist(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int alloc_metalist(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { const char *desc = (const char *)private; @@ -1121,7 +1121,7 @@ static int alloc_metalist(struct iptr iptr, struct lgfs2_buffer_head **bh, int h return META_IS_GOOD; }
-static int alloc_data(struct lgfs2_inode *ip, uint64_t metablock, +static int alloc_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { @@ -1140,7 +1140,7 @@ static int alloc_data(struct lgfs2_inode *ip, uint64_t metablock, return 0; }
-static int alloc_leaf(struct lgfs2_inode *ip, uint64_t block, void *private) +static int alloc_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private) { int q;
@@ -1177,12 +1177,12 @@ static struct metawalk_fxns alloc_fxns = { * have been freed in the bitmap. We need to set the inode address as free * as well. */ -static int pass1_check_metatree(struct lgfs2_inode *ip, +static int pass1_check_metatree(struct fsck_cx *cx, struct lgfs2_inode *ip, struct metawalk_fxns *pass) { int error;
- error = check_metatree(ip, pass); + error = check_metatree(cx, ip, pass); if (error) gfs2_blockmap_set(bl, ip->i_num.in_addr, GFS2_BLKST_FREE); return error; @@ -1205,7 +1205,7 @@ static int pass1_check_metatree(struct lgfs2_inode *ip, * So it's only our blockmap that now disagrees with the rgrp bitmap, so we * need to fix only that. */ -static void reprocess_inode(struct lgfs2_inode *ip, const char *desc) +static void reprocess_inode(struct fsck_cx *cx, struct lgfs2_inode *ip, const char *desc) { int error;
@@ -1213,7 +1213,7 @@ static void reprocess_inode(struct lgfs2_inode *ip, const char *desc) log_info(_("%s inode %"PRIu64" (0x%"PRIx64") had blocks added; reprocessing " "its metadata tree at height=%d.\n"), desc, ip->i_num.in_addr, ip->i_num.in_addr, ip->i_height); - error = pass1_check_metatree(ip, &alloc_fxns); + error = pass1_check_metatree(cx, ip, &alloc_fxns); if (error) log_err( _("Error %d reprocessing the %s metadata tree.\n"), error, desc); @@ -1222,7 +1222,7 @@ static void reprocess_inode(struct lgfs2_inode *ip, const char *desc) /* * handle_ip - process an incore structure representing a dinode. */ -static int handle_ip(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) +static int handle_ip(struct fsck_cx *cx, struct lgfs2_inode *ip) { int error; struct block_count bc = {0}; @@ -1236,7 +1236,7 @@ static int handle_ip(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) so it's better to check it up front and delete the inode if there is corruption. */ rangecheck_fxns.private = &bad_pointers; - error = pass1_check_metatree(ip, &rangecheck_fxns); + error = pass1_check_metatree(cx, ip, &rangecheck_fxns); if (bad_pointers > BAD_POINTER_TOLERANCE) { log_err(_("Error: inode %"PRIu64" (0x%"PRIx64") has more than %d bad pointers.\n"), ip->i_num.in_addr, ip->i_num.in_addr, BAD_POINTER_TOLERANCE); @@ -1264,13 +1264,13 @@ static int handle_ip(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) lf_blks = lf_dip->i_blocks;
pass1_fxns.private = &bc; - error = pass1_check_metatree(ip, &pass1_fxns); + error = pass1_check_metatree(cx, ip, &pass1_fxns);
/* Pass1 may have added some blocks to lost+found by virtue of leafs that were misplaced. If it did, we need to reprocess lost+found to correctly account for its blocks. */ if (lf_dip && lf_dip->i_blocks != lf_blks) - reprocess_inode(lf_dip, "lost+found"); + reprocess_inode(cx, lf_dip, "lost+found");
/* We there was an error, we return 0 because we want fsck to continue and analyze the other dinodes as well. */ @@ -1278,7 +1278,7 @@ static int handle_ip(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) return 0;
if (!error) { - error = check_inode_eattr(ip, &pass1_fxns); + error = check_inode_eattr(cx, ip, &pass1_fxns);
if (error) { if (!query(_("Clear the bad Extended Attributes? " @@ -1291,7 +1291,7 @@ static int handle_ip(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) "inode %"PRIu64" (0x%"PRIx64").\n"), ip->i_num.in_addr, ip->i_num.in_addr); eattr_undo_fxns.private = &bc; - check_inode_eattr(ip, &eattr_undo_fxns); + check_inode_eattr(cx, ip, &eattr_undo_fxns); ask_remove_inode_eattr(ip, &bc); return 1; } @@ -1346,14 +1346,14 @@ static void check_i_goal(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) * handle_di - This is now a wrapper function that takes a lgfs2_buffer_head * and calls handle_ip, which takes an in-code dinode structure. */ -static int handle_di(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd, +static int handle_di(struct fsck_cx *cx, struct lgfs2_rgrp_tree *rgd, struct lgfs2_buffer_head *bh) { int error = 0; uint64_t block = bh->b_blocknr; struct lgfs2_inode *ip;
- ip = fsck_inode_get(sdp, rgd, bh); + ip = fsck_inode_get(cx->sdp, rgd, bh);
if (ip->i_num.in_addr != block) { log_err(_("Inode #%"PRIu64" (0x%"PRIx64"): Bad inode address found: %"PRIu64 @@ -1367,7 +1367,7 @@ static int handle_di(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd, log_err(_("Address in inode at block #%"PRIu64" (0x%"PRIx64" not fixed\n"), block, block); } - if (sdp->gfs1 && ip->i_num.in_formal_ino != block) { + if (cx->sdp->gfs1 && ip->i_num.in_formal_ino != block) { log_err(_("Inode #%"PRIu64" (0x%"PRIx64"): GFS1 formal inode number " "mismatch: was %"PRIu64" (0x%"PRIx64")\n"), block, block, ip->i_num.in_formal_ino, ip->i_num.in_formal_ino); @@ -1379,8 +1379,8 @@ static int handle_di(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd, log_err(_("Inode number in inode at block %"PRIu64" (0x%"PRIx64") not fixed\n"), block, block); } - check_i_goal(sdp, ip); - error = handle_ip(sdp, ip); + check_i_goal(cx->sdp, ip); + error = handle_ip(cx, ip); fsck_inode_put(&ip); return error; } @@ -1389,7 +1389,7 @@ static int handle_di(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd, /* Should work for all system inodes: root, master, jindex, per_node, etc. */ /* We have to pass the sysinode as ** because the pointer may change out from under the reference by way of the builder() function. */ -static int check_system_inode(struct lgfs2_sbd *sdp, +static int check_system_inode(struct fsck_cx *cx, struct lgfs2_inode **sysinode, const char *filename, int builder(struct lgfs2_sbd *sdp), int isdir, @@ -1410,7 +1410,7 @@ static int check_system_inode(struct lgfs2_sbd *sdp, log_err(_("Found invalid system dinode at block %"PRIu64" (0x%"PRIx64")\n"), iblock, iblock); gfs2_blockmap_set(bl, iblock, GFS2_BLKST_FREE); - check_n_fix_bitmap(sdp, (*sysinode)->i_rgd, iblock, 0, + check_n_fix_bitmap(cx->sdp, (*sysinode)->i_rgd, iblock, 0, GFS2_BLKST_FREE); lgfs2_inode_put(sysinode); } @@ -1465,15 +1465,15 @@ static int check_system_inode(struct lgfs2_sbd *sdp, if (query(_("Create new %s system inode? (y/n) "), filename)) { log_err( _("Rebuilding system file "%s"\n"), filename); - error = builder(sdp); + error = builder(cx->sdp); if (error) { log_err( _("Error rebuilding system " "inode %s: Cannot continue\n"), filename); return error; } - if (*sysinode == sdp->md.jiinode) - ji_update(sdp); + if (*sysinode == cx->sdp->md.jiinode) + ji_update(cx->sdp); fsck_blockmap_set(*sysinode, (*sysinode)->i_num.in_addr, filename, GFS2_BLKST_DINODE); ds.q = GFS2_BLKST_DINODE; @@ -1487,14 +1487,14 @@ static int check_system_inode(struct lgfs2_sbd *sdp, return -1; } } - if (is_dir(*sysinode, sdp->gfs1)) { + if (is_dir(*sysinode, cx->sdp->gfs1)) { struct block_count bc = {0};
sysdir_fxns.private = &bc; if ((*sysinode)->i_flags & GFS2_DIF_EXHASH) - pass1_check_metatree(*sysinode, &sysdir_fxns); + pass1_check_metatree(cx, *sysinode, &sysdir_fxns); else { - err = check_linear_dir(*sysinode, (*sysinode)->i_bh, + err = check_linear_dir(cx, *sysinode, (*sysinode)->i_bh, &sysdir_fxns); /* If we encountered an error in our directory check we should still call handle_ip, but return the @@ -1504,8 +1504,8 @@ static int check_system_inode(struct lgfs2_sbd *sdp, "directory entries.\n"), filename); } } - check_i_goal(sdp, *sysinode); - error = handle_ip(sdp, *sysinode); + check_i_goal(cx->sdp, *sysinode); + error = handle_ip(cx, *sysinode); return error ? error : err; }
@@ -1604,20 +1604,18 @@ static int build_quota(struct lgfs2_sbd *sdp) return 0; }
-static int check_system_inodes(struct lgfs2_sbd *sdp) +static int check_system_inodes(struct fsck_cx *cx) { + struct lgfs2_sbd *sdp = cx->sdp; int journal_count;
- /******************************************************************* - ******* Check the system inode integrity ************* - *******************************************************************/ /* Mark the master system dinode as a "dinode" in the block map. All other system dinodes in master will be taken care of by function resuscitate_metalist. But master won't since it has no parent.*/ if (!sdp->gfs1) { fsck_blockmap_set(sdp->master_dir, sdp->master_dir->i_num.in_addr, "master", GFS2_BLKST_DINODE); - if (check_system_inode(sdp, &sdp->master_dir, "master", + if (check_system_inode(cx, &sdp->master_dir, "master", lgfs2_build_master, 1, NULL, 1)) { stack; return -1; @@ -1627,40 +1625,40 @@ static int check_system_inodes(struct lgfs2_sbd *sdp) for master, since it has no parent. */ fsck_blockmap_set(sdp->md.rooti, sdp->md.rooti->i_num.in_addr, "root", GFS2_BLKST_DINODE); - if (check_system_inode(sdp, &sdp->md.rooti, "root", lgfs2_build_root, 1, + if (check_system_inode(cx, &sdp->md.rooti, "root", lgfs2_build_root, 1, NULL, 0)) { stack; return -1; } if (!sdp->gfs1 && - check_system_inode(sdp, &sdp->md.inum, "inum", build_inum, 0, + check_system_inode(cx, &sdp->md.inum, "inum", build_inum, 0, sdp->master_dir, 1)) { stack; return -1; } - if (check_system_inode(sdp, &sdp->md.statfs, "statfs", build_statfs, 0, + if (check_system_inode(cx, &sdp->md.statfs, "statfs", build_statfs, 0, sdp->master_dir, !sdp->gfs1)) { stack; return -1; } - if (check_system_inode(sdp, &sdp->md.jiinode, "jindex", build_jindex, + if (check_system_inode(cx, &sdp->md.jiinode, "jindex", build_jindex, (sdp->gfs1 ? 0 : 1), sdp->master_dir, !sdp->gfs1)) { stack; return -1; } - if (check_system_inode(sdp, &sdp->md.riinode, "rindex", build_rindex, + if (check_system_inode(cx, &sdp->md.riinode, "rindex", build_rindex, 0, sdp->master_dir, !sdp->gfs1)) { stack; return -1; } - if (check_system_inode(sdp, &sdp->md.qinode, "quota", build_quota, + if (check_system_inode(cx, &sdp->md.qinode, "quota", build_quota, 0, sdp->master_dir, !sdp->gfs1)) { stack; return -1; } if (!sdp->gfs1 && - check_system_inode(sdp, &sdp->md.pinode, "per_node", + check_system_inode(cx, &sdp->md.pinode, "per_node", build_per_node, 1, sdp->master_dir, 1)) { stack; return -1; @@ -1689,7 +1687,7 @@ static int check_system_inodes(struct lgfs2_sbd *sdp) char jname[16];
sprintf(jname, "journal%d", sdp->md.journals); - if (check_system_inode(sdp, &sdp->md.journal[sdp->md.journals], + if (check_system_inode(cx, &sdp->md.journal[sdp->md.journals], jname, build_a_journal, 0, sdp->md.jiinode, 1)) { stack; @@ -1700,9 +1698,10 @@ static int check_system_inodes(struct lgfs2_sbd *sdp) return 0; }
-static int pass1_process_bitmap(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd, uint64_t *ibuf, unsigned n) +static int pass1_process_bitmap(struct fsck_cx *cx, struct lgfs2_rgrp_tree *rgd, uint64_t *ibuf, unsigned n) { struct lgfs2_buffer_head *bh; + struct lgfs2_sbd *sdp = cx->sdp; unsigned i; uint64_t block; struct lgfs2_inode *ip; @@ -1804,7 +1803,7 @@ static int pass1_process_bitmap(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *r log_err(_("Found invalid inode at block %"PRIu64" (0x%"PRIx64")\n"), block, block); check_n_fix_bitmap(sdp, rgd, block, 0, GFS2_BLKST_FREE); - } else if (handle_di(sdp, rgd, bh) < 0) { + } else if (handle_di(cx, rgd, bh) < 0) { stack; lgfs2_brelse(bh); gfs2_special_free(&gfs1_rindex_blks); @@ -1823,10 +1822,10 @@ static int pass1_process_bitmap(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *r return 0; }
-static int pass1_process_rgrp(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd) +static int pass1_process_rgrp(struct fsck_cx *cx, struct lgfs2_rgrp_tree *rgd) { unsigned k, n, i; - uint64_t *ibuf = malloc(sdp->sd_bsize * GFS2_NBBY * sizeof(uint64_t)); + uint64_t *ibuf = malloc(cx->sdp->sd_bsize * GFS2_NBBY * sizeof(uint64_t)); int ret = 0;
if (ibuf == NULL) @@ -1836,7 +1835,7 @@ static int pass1_process_rgrp(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd n = lgfs2_bm_scan(rgd, k, ibuf, GFS2_BLKST_DINODE);
if (n) { - ret = pass1_process_bitmap(sdp, rgd, ibuf, n); + ret = pass1_process_bitmap(cx, rgd, ibuf, n); if (ret) goto out; } @@ -1848,7 +1847,7 @@ static int pass1_process_rgrp(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd resource group and mark them specially so we can count them properly in pass5. */ - if (!sdp->gfs1) + if (!cx->sdp->gfs1) continue;
n = lgfs2_bm_scan(rgd, k, ibuf, GFS2_BLKST_UNLINKED); @@ -1986,7 +1985,7 @@ int pass1(struct fsck_cx *cx) * the sweeps start that we won't find otherwise? */
/* Make sure the system inodes are okay & represented in the bitmap. */ - check_system_inodes(sdp); + check_system_inodes(cx);
/* So, do we do a depth first search starting at the root * inode, or use the rg bitmaps, or just read every fs block @@ -2020,7 +2019,7 @@ int pass1(struct fsck_cx *cx) gfs2_meta_rgrp);*/ }
- ret = pass1_process_rgrp(sdp, rgd); + ret = pass1_process_rgrp(cx, rgd); if (ret) goto out; } diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index 76c01fb3..9e78bd14 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -41,7 +41,7 @@ struct meta_blk_ref { int off; /* offset to the reference within the buffer */ };
-static int clone_data(struct lgfs2_inode *ip, uint64_t metablock, +static int clone_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr);
@@ -66,7 +66,7 @@ static void log_inode_reference(struct duptree *dt, osi_list_t *tmp, int inval) reftypestring); }
-static int findref_meta(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int findref_meta(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { *is_valid = 1; @@ -74,7 +74,7 @@ static int findref_meta(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, return META_IS_GOOD; }
-static int findref_data(struct lgfs2_inode *ip, uint64_t metablock, +static int findref_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { @@ -89,7 +89,7 @@ static int findref_data(struct lgfs2_inode *ip, uint64_t metablock, return META_IS_GOOD; }
-static void clone_data_block(struct lgfs2_sbd *sdp, struct duptree *dt, +static void clone_data_block(struct fsck_cx *cx, struct duptree *dt, struct inode_with_dups *id) { struct meta_blk_ref metaref = { .block = dt->block, }; @@ -108,17 +108,17 @@ static void clone_data_block(struct lgfs2_sbd *sdp, struct duptree *dt, log_warn(_("The duplicate reference was not cloned.\n")); return; } - ip = fsck_load_inode(sdp, id->block_no); - check_metatree(ip, &find1ref_fxns); + ip = fsck_load_inode(cx->sdp, id->block_no); + check_metatree(cx, ip, &find1ref_fxns); if (metaref.metablock == 0) { log_err(_("Unable to clone data block.\n")); } else { if (metaref.metablock != id->block_no) - bh = lgfs2_bread(sdp, metaref.metablock); + bh = lgfs2_bread(cx->sdp, metaref.metablock); else bh = ip->i_bh; ptr = (__be64 *)bh->b_data + metaref.off; - clone_data(ip, 0, dt->block, &clone, bh, ptr); + clone_data(cx, ip, 0, dt->block, &clone, bh, ptr); if (metaref.metablock != id->block_no) lgfs2_brelse(bh); else @@ -175,7 +175,7 @@ static void revise_dup_handler(uint64_t dup_blk, struct dup_handler *dh) * acceptable_ref - Delete dinodes that reference the given block as anything * _but_ this type. Try to save references as this type. */ -static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, +static void resolve_dup_references(struct fsck_cx *cx, struct duptree *dt, osi_list_t *ref_list, struct dup_handler *dh, int inval, int acceptable_ref) @@ -210,7 +210,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, return;
this_ref = get_ref_type(id); - q = bitmap_type(sdp, id->block_no); + q = bitmap_type(cx->sdp, id->block_no); if (inval) log_warn( _("Invalid ")); /* FIXME: If we already found an acceptable reference to this @@ -238,7 +238,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, it's data or metadata inside a journal, the reference should take priority over user dinodes that reference the block. */ - if (!found_good_ref && fsck_system_inode(sdp, id->block_no)) { + if (!found_good_ref && fsck_system_inode(cx->sdp, id->block_no)) { found_good_ref = 1; continue; /* don't delete the dinode */ } @@ -265,7 +265,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, } } else if (acceptable_ref == REF_TYPES && this_ref == REF_AS_DATA) { - clone_data_block(sdp, dt, id); + clone_data_block(cx, dt, id); dup_listent_delete(dt, id); revise_dup_handler(dt->block, dh); continue; @@ -291,7 +291,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, log_warn(_("Pass1b is deleting inode %"PRIu64" (0x%"PRIx64").\n"), id->block_no, id->block_no);
- ip = fsck_load_inode(sdp, id->block_no); + ip = fsck_load_inode(cx->sdp, id->block_no); /* If we've already deleted this dinode, don't try to delete it again. That could free blocks that used to be duplicate references that are now resolved (and gone). */ @@ -316,7 +316,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, (dh->ref_inode_count)--; } else { /* Clear the EAs for the inode first */ - check_inode_eattr(ip, &pass1b_fxns_delete); + check_inode_eattr(cx, ip, &pass1b_fxns_delete); (dh->ref_inode_count)--; } /* If the reference was as metadata or data, we've got @@ -352,7 +352,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, /* FIXME: other option should be to duplicate the block for each duplicate and point the metadata at the cloned blocks */ - check_metatree(ip, &pass1b_fxns_delete); + check_metatree(cx, ip, &pass1b_fxns_delete); } } /* Now we've got to go through and delete any other duplicate @@ -370,7 +370,7 @@ static void resolve_dup_references(struct lgfs2_sbd *sdp, struct duptree *dt, return; }
-static int clone_check_meta(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int clone_check_meta(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -387,7 +387,7 @@ static int clone_check_meta(struct iptr iptr, struct lgfs2_buffer_head **bh, int * This function remembers the first reference to the specified block, and * clones all subsequent references to it (with permission). */ -static int clone_data(struct lgfs2_inode *ip, uint64_t metablock, +static int clone_data(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { @@ -452,7 +452,7 @@ static int clone_data(struct lgfs2_inode *ip, uint64_t metablock, * This function traverses the metadata tree of an inode, cloning all * but the first reference to a duplicate block reference. */ -static void clone_dup_ref_in_inode(struct lgfs2_inode *ip, struct duptree *dt) +static void clone_dup_ref_in_inode(struct fsck_cx *cx, struct lgfs2_inode *ip, struct duptree *dt) { int error; struct clone_target clonet = {.dup_block = dt->block, .first = 1}; @@ -465,7 +465,7 @@ static void clone_dup_ref_in_inode(struct lgfs2_inode *ip, struct duptree *dt) log_err(_("There are multiple references to block %"PRIu64" (0x%"PRIx64") in " "inode %"PRIu64" (0x%"PRIx64")\n"), ip->i_num.in_addr, ip->i_num.in_addr, dt->block, dt->block); - error = check_metatree(ip, &pass1b_fxns_clone); + error = check_metatree(cx, ip, &pass1b_fxns_clone); if (error) { log_err(_("Error cloning duplicate reference(s) to block %"PRIu64 " (0x%"PRIx64").\n"), dt->block, dt->block); @@ -512,9 +512,10 @@ static int set_ip_bitmap(struct lgfs2_inode *ip) return 0; }
-static void resolve_last_reference(struct lgfs2_sbd *sdp, struct duptree *dt, +static void resolve_last_reference(struct fsck_cx *cx, struct duptree *dt, enum dup_ref_type acceptable_ref) { + struct lgfs2_sbd *sdp = cx->sdp; struct lgfs2_inode *ip; struct inode_with_dups *id; osi_list_t *tmp; @@ -536,7 +537,7 @@ static void resolve_last_reference(struct lgfs2_sbd *sdp, struct duptree *dt, ip = fsck_load_inode(sdp, id->block_no);
if (dt->dup_flags & DUPFLAG_REF1_IS_DUPL) - clone_dup_ref_in_inode(ip, dt); + clone_dup_ref_in_inode(cx, ip, dt);
q = bitmap_type(sdp, id->block_no); if (q == GFS2_BLKST_FREE) { @@ -601,7 +602,7 @@ static void resolve_last_reference(struct lgfs2_sbd *sdp, struct duptree *dt, * This function should resolve and delete the duplicate block reference given, * iow dt. */ -static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) +static int handle_dup_blk(struct fsck_cx *cx, struct duptree *dt) { osi_list_t *tmp; struct dup_handler dh = {0}; @@ -630,7 +631,7 @@ static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) references to it as metadata. Dinodes with such references are clearly corrupt and need to be deleted. And if we're left with a single reference, problem solved. */ - bh = lgfs2_bread(sdp, dt->block); + bh = lgfs2_bread(cx->sdp, dt->block); cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic; ctype = ((struct gfs2_meta_header *)(bh->b_data))->mh_type; lgfs2_brelse(bh); @@ -674,7 +675,7 @@ static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) "(0x%"PRIx64") that were previously marked " "invalid.\n"), dt->block, dt->block); - resolve_dup_references(sdp, dt, &dt->ref_invinode_list, + resolve_dup_references(cx, dt, &dt->ref_invinode_list, &dh, 1, REF_TYPES); revise_dup_handler(dup_blk, &dh); } @@ -688,7 +689,7 @@ static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) "Step 2: Eliminate references to block %"PRIu64" " "(0x%"PRIx64") that need the wrong block type.\n"), dt->block, dt->block); - resolve_dup_references(sdp, dt, &dt->ref_inode_list, &dh, 0, + resolve_dup_references(cx, dt, &dt->ref_inode_list, &dh, 0, acceptable_ref); revise_dup_handler(dup_blk, &dh); } @@ -701,7 +702,7 @@ static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) "Step 3: Choose one reference to block %"PRIu64" " "(0x%"PRIx64") to keep.\n"), dt->block, dt->block); - resolve_dup_references(sdp, dt, &dt->ref_inode_list, &dh, 0, + resolve_dup_references(cx, dt, &dt->ref_inode_list, &dh, 0, REF_TYPES); revise_dup_handler(dup_blk, &dh); } @@ -709,7 +710,7 @@ static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) reference, use it to determine the correct block type for our blockmap and bitmap. */ if (dh.ref_inode_count == 1 && !osi_list_empty(&dt->ref_inode_list)) { - resolve_last_reference(sdp, dt, acceptable_ref); + resolve_last_reference(cx, dt, acceptable_ref); } else { /* They may have answered no and not fixed all references. */ log_debug( _("All duplicate references to block 0x%"PRIx64" were processed.\n"), dup_blk); @@ -723,20 +724,20 @@ static int handle_dup_blk(struct lgfs2_sbd *sdp, struct duptree *dt) dup_blk, dup_blk); if (dh.dt) dup_delete(dh.dt); - check_n_fix_bitmap(sdp, NULL, dup_blk, 0, + check_n_fix_bitmap(cx->sdp, NULL, dup_blk, 0, GFS2_BLKST_FREE); } } return 0; }
-static int check_leaf_refs(struct lgfs2_inode *ip, uint64_t block, +static int check_leaf_refs(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, void *private) { return add_duplicate_ref(ip, block, REF_AS_META, 1, INODE_VALID); }
-static int check_metalist_refs(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int check_metalist_refs(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -747,14 +748,14 @@ static int check_metalist_refs(struct iptr iptr, struct lgfs2_buffer_head **bh, return add_duplicate_ref(ip, block, REF_AS_META, 1, INODE_VALID); }
-static int check_data_refs(struct lgfs2_inode *ip, uint64_t metablock, +static int check_data_refs(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bh, __be64 *ptr) { return add_duplicate_ref(ip, block, REF_AS_DATA, 1, INODE_VALID); }
-static int check_eattr_indir_refs(struct lgfs2_inode *ip, uint64_t block, +static int check_eattr_indir_refs(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { @@ -768,7 +769,7 @@ static int check_eattr_indir_refs(struct lgfs2_inode *ip, uint64_t block, return error; }
-static int check_eattr_leaf_refs(struct lgfs2_inode *ip, uint64_t block, +static int check_eattr_leaf_refs(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { @@ -781,7 +782,7 @@ static int check_eattr_leaf_refs(struct lgfs2_inode *ip, uint64_t block, return error; }
-static int check_eattr_entry_refs(struct lgfs2_inode *ip, +static int check_eattr_entry_refs(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, @@ -790,7 +791,7 @@ static int check_eattr_entry_refs(struct lgfs2_inode *ip, return 0; }
-static int check_eattr_extentry_refs(struct lgfs2_inode *ip, int i, +static int check_eattr_extentry_refs(struct fsck_cx *cx, struct lgfs2_inode *ip, int i, __be64 *ea_data_ptr, struct lgfs2_buffer_head *leaf_bh, uint32_t tot_ealen, @@ -811,7 +812,7 @@ static int check_eattr_extentry_refs(struct lgfs2_inode *ip, int i,
/* Finds all references to duplicate blocks in the metadata */ /* Finds all references to duplicate blocks in the metadata */ -static int find_block_ref(struct lgfs2_sbd *sdp, uint64_t inode) +static int find_block_ref(struct fsck_cx *cx, uint64_t inode) { struct lgfs2_inode *ip; int error = 0; @@ -826,12 +827,12 @@ static int find_block_ref(struct lgfs2_sbd *sdp, uint64_t inode) .check_eattr_extentry = check_eattr_extentry_refs, };
- ip = fsck_load_inode(sdp, inode); /* lgfs2_bread, inode_get */ + ip = fsck_load_inode(cx->sdp, inode); /* lgfs2_bread, inode_get */
/* double-check the meta header just to be sure it's metadata */ if (ip->i_magic != GFS2_MAGIC || ip->i_mh_type != GFS2_METATYPE_DI) { - if (!sdp->gfs1) + if (!cx->sdp->gfs1) log_debug(_("Block %"PRIu64" (0x%"PRIx64") is not a dinode.\n"), inode, inode); error = 1; @@ -841,13 +842,13 @@ static int find_block_ref(struct lgfs2_sbd *sdp, uint64_t inode) add_duplicate_ref(ip, inode, REF_IS_INODE, 1, INODE_VALID);
/* Check this dinode's metadata for references to known duplicates */ - error = check_metatree(ip, &find_refs); + error = check_metatree(cx, ip, &find_refs); if (error < 0) stack;
/* Check for ea references in the inode */ if (!error) - error = check_inode_eattr(ip, &find_refs); + error = check_inode_eattr(cx, ip, &find_refs);
out: fsck_inode_put(&ip); /* out, lgfs2_brelse, free */ @@ -900,7 +901,7 @@ int pass1b(struct fsck_cx *cx) }
display_progress(i); - if (find_block_ref(sdp, i) < 0) { + if (find_block_ref(cx, i) < 0) { stack; rc = FSCK_ERROR; goto out; @@ -915,7 +916,7 @@ out: while ((n = osi_first(&dup_blocks))) { dt = (struct duptree *)n; if (!skip_this_pass && !rc) /* no error & not asked to skip the rest */ - handle_dup_blk(sdp, dt); + handle_dup_blk(cx, dt); } return rc; } diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c index 62f84516..e5734fd6 100644 --- a/gfs2/fsck/pass2.c +++ b/gfs2/fsck/pass2.c @@ -95,14 +95,14 @@ static int set_dotdot_dir(struct lgfs2_sbd *sdp, uint64_t childblock, struct lgf return 0; }
-static int check_eattr_indir(struct lgfs2_inode *ip, uint64_t block, +static int check_eattr_indir(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { *bh = lgfs2_bread(ip->i_sbd, block); return 0; } -static int check_eattr_leaf(struct lgfs2_inode *ip, uint64_t block, +static int check_eattr_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t block, uint64_t parent, struct lgfs2_buffer_head **bh, void *private) { @@ -245,7 +245,7 @@ static int hash_table_max(int lindex, struct lgfs2_inode *ip, lindex - 1; }
-static int check_leaf_depth(struct lgfs2_inode *ip, uint64_t leaf_no, +static int check_leaf_depth(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t leaf_no, int ref_count, struct lgfs2_buffer_head *lbh) { struct gfs2_leaf *leaf = (struct gfs2_leaf *)lbh->b_data; @@ -290,7 +290,7 @@ static int check_leaf_depth(struct lgfs2_inode *ip, uint64_t leaf_no, * Returns: 1 if the dirent is to be removed, 0 if it needs to be kept, * or -1 on error */ -static int wrong_leaf(struct lgfs2_inode *ip, struct lgfs2_inum *entry, +static int wrong_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, struct lgfs2_inum *entry, const char *tmp_name, int *lindex, int lindex_max, int hash_index, struct lgfs2_buffer_head *bh, struct dir_status *ds, struct gfs2_dirent *dent, @@ -332,7 +332,7 @@ static int wrong_leaf(struct lgfs2_inode *ip, struct lgfs2_inum *entry, break; } dest_lbh = lgfs2_bread(sdp, planned_leaf); - check_leaf_depth(ip, planned_leaf, dest_ref, dest_lbh); + check_leaf_depth(cx, ip, planned_leaf, dest_ref, dest_lbh); lgfs2_brelse(dest_lbh); free(tbl);
@@ -420,7 +420,7 @@ static int wrong_leaf(struct lgfs2_inode *ip, struct lgfs2_inum *entry, * * Returns: 1 means corruption, nuke the dentry, 0 means checks pass */ -static int basic_dentry_checks(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int basic_dentry_checks(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct lgfs2_inum *entry, const char *tmp_name, uint32_t *count, struct lgfs2_dirent *d, struct dir_status *ds, int *q, @@ -562,7 +562,7 @@ static int basic_dentry_checks(struct lgfs2_inode *ip, struct gfs2_dirent *dent, entry_ip = ip; else entry_ip = fsck_load_inode(sdp, entry->in_addr); - check_inode_eattr(entry_ip, &delete_eattrs); + check_inode_eattr(cx, entry_ip, &delete_eattrs); if (entry_ip != ip) fsck_inode_put(&entry_ip); return 1; @@ -614,7 +614,7 @@ static int basic_dentry_checks(struct lgfs2_inode *ip, struct gfs2_dirent *dent, return 0; }
-static int dirref_find(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int dirref_find(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, void *private) @@ -678,8 +678,7 @@ out: * the same, that's an error, and we need to delete the damaged original * dentry, since we failed to detect the problem earlier. */ -static int check_suspicious_dirref(struct lgfs2_sbd *sdp, - struct lgfs2_inum *entry) +static int check_suspicious_dirref(struct fsck_cx *cx, struct lgfs2_inum *entry) { struct osi_node *tmp, *next = NULL; struct dir_info *dt; @@ -700,12 +699,12 @@ static int check_suspicious_dirref(struct lgfs2_sbd *sdp, dirblk = dt->dinode.in_addr; if (skip_this_pass || fsck_abort) /* asked to skip the rest */ break; - ip = fsck_load_inode(sdp, dirblk); + ip = fsck_load_inode(cx->sdp, dirblk); if (ip == NULL) { stack; return FSCK_ERROR; } - error = check_dir(sdp, ip, &dirref_hunt); + error = check_dir(cx, ip, &dirref_hunt); fsck_inode_put(&ip); /* Error just means we found the dentry and dealt with it. */ if (error) @@ -718,7 +717,7 @@ static int check_suspicious_dirref(struct lgfs2_sbd *sdp,
/* FIXME: should maybe refactor this a bit - but need to deal with * FIXMEs internally first */ -static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int check_dentry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, void *priv) @@ -747,7 +746,7 @@ static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, else strncpy(tmp_name, filename, MAX_FILENAME - 1);
- error = basic_dentry_checks(ip, dent, &entry, tmp_name, count, &d, + error = basic_dentry_checks(cx, ip, dent, &entry, tmp_name, count, &d, ds, &q, bh, &isdir); if (error) goto nuke_dentry; @@ -769,7 +768,7 @@ static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, entry_ip = ip; else entry_ip = fsck_load_inode(sdp, entry.in_addr); - check_inode_eattr(entry_ip, &delete_eattrs); + check_inode_eattr(cx, entry_ip, &delete_eattrs); if (entry_ip != ip) fsck_inode_put(&entry_ip); goto nuke_dentry; @@ -795,7 +794,7 @@ static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, entry_ip = ip; else entry_ip = fsck_load_inode(sdp, entry.in_addr); - check_inode_eattr(entry_ip, &delete_eattrs); + check_inode_eattr(cx, entry_ip, &delete_eattrs); if (entry_ip != ip) fsck_inode_put(&entry_ip); goto nuke_dentry; @@ -822,7 +821,7 @@ static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, entry_ip = ip; else entry_ip = fsck_load_inode(sdp, entry.in_addr); - check_inode_eattr(entry_ip, &delete_eattrs); + check_inode_eattr(cx, entry_ip, &delete_eattrs); if (entry_ip != ip) fsck_inode_put(&entry_ip);
@@ -840,7 +839,7 @@ static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, entry_ip = ip; else entry_ip = fsck_load_inode(sdp, entry.in_addr); - check_inode_eattr(entry_ip, &delete_eattrs); + check_inode_eattr(cx, entry_ip, &delete_eattrs); if (entry_ip != ip) fsck_inode_put(&entry_ip);
@@ -867,7 +866,7 @@ static int check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, if (hash_index < *lindex || hash_index > lindex_max) { int nuke_dent;
- nuke_dent = wrong_leaf(ip, &entry, tmp_name, lindex, + nuke_dent = wrong_leaf(cx, ip, &entry, tmp_name, lindex, lindex_max, hash_index, bh, ds, dent, &d, prev_de, count, q); if (nuke_dent) @@ -902,7 +901,7 @@ dentry_is_valid: /* This directory inode links to this inode via this dentry */ error = incr_link_count(entry, ip, _("valid reference")); if (error == INCR_LINK_CHECK_ORIG) { - error = check_suspicious_dirref(sdp, &entry); + error = check_suspicious_dirref(cx, &entry); } else if (error == INCR_LINK_INO_MISMATCH) { log_err("incr_link_count err=%d.\n", error); if (bad_formal_ino(ip, dent, entry, tmp_name, q, &d, bh) == 1) @@ -1070,7 +1069,7 @@ static void pad_with_leafblks(struct lgfs2_inode *ip, __be64 *tbl, * directory entries to lost+found so we don't overwrite the good leaf. Then * we need to pad the gap we leave. */ -static int lost_leaf(struct lgfs2_inode *ip, __be64 *tbl, uint64_t leafno, +static int lost_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl, uint64_t leafno, int ref_count, int lindex, struct lgfs2_buffer_head *bh) { char *filename; @@ -1115,7 +1114,7 @@ static int lost_leaf(struct lgfs2_inode *ip, __be64 *tbl, uint64_t leafno, struct dir_status ds = {0}; int q = 0;
- error = basic_dentry_checks(ip, dent, &de.dr_inum, + error = basic_dentry_checks(cx, ip, dent, &de.dr_inum, tmp_name, &count, &de, &ds, &q, bh, &isdir); if (error) { @@ -1164,7 +1163,7 @@ static int lost_leaf(struct lgfs2_inode *ip, __be64 *tbl, uint64_t leafno, return 1; }
-static int basic_check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, +static int basic_check_dentry(struct fsck_cx *cx, struct lgfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct lgfs2_buffer_head *bh, char *filename, uint32_t *count, int *lindex, void *priv) @@ -1191,7 +1190,7 @@ static int basic_check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, else strncpy(tmp_name, filename, MAX_FILENAME - 1);
- error = basic_dentry_checks(ip, dent, &entry, tmp_name, count, de, + error = basic_dentry_checks(cx, ip, dent, &entry, tmp_name, count, de, ds, &q, bh, &isdir); if (error) { lgfs2_dirent2_del(ip, bh, prev_de, dent); @@ -1209,7 +1208,7 @@ static int basic_check_dentry(struct lgfs2_inode *ip, struct gfs2_dirent *dent, * so that they replace the bad ones. We have to hack up the old * leaf a bit, but it's better than deleting the whole directory, * which is what used to happen before. */ -static int pass2_repair_leaf(struct lgfs2_inode *ip, uint64_t *leaf_no, +static int pass2_repair_leaf(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t *leaf_no, int lindex, int ref_count, const char *msg) { int new_leaf_blks = 0, error, refs; @@ -1287,7 +1286,7 @@ static struct metawalk_fxns leafck_fxns = { * * Returns: 0 - no changes made, or X if changes were made */ -static int fix_hashtable(struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, +static int fix_hashtable(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, uint64_t leafblk, int lindex, uint32_t proper_start, int len, int *proper_len, int factor) { @@ -1311,7 +1310,7 @@ static int fix_hashtable(struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize,
memset(&leaf, 0, sizeof(leaf)); leaf_no = leafblk; - error = check_leaf(ip, lindex, &leafck_fxns, &leaf_no, &leaf, &len); + error = check_leaf(cx, ip, lindex, &leafck_fxns, &leaf_no, &leaf, &len); if (error) { log_debug("Leaf repaired while fixing the hash table.\n"); error = 0; @@ -1323,7 +1322,7 @@ static int fix_hashtable(struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, log_err(_("This leaf block's depth (%d) is too big for this " "dinode's depth (%d)\n"), leaf.lf_depth, ip->i_depth); - error = lost_leaf(ip, tbl, leafblk, len, lindex, lbh); + error = lost_leaf(cx, ip, tbl, leafblk, len, lindex, lbh); lgfs2_brelse(lbh); return error; } @@ -1358,7 +1357,7 @@ static int fix_hashtable(struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, "bounds for where it appears in the hash table " "(%d - %d)\n"), hash_index, lindex, lindex + *proper_len); - error = lost_leaf(ip, tbl, leafblk, len, lindex, lbh); + error = lost_leaf(cx, ip, tbl, leafblk, len, lindex, lbh); lgfs2_brelse(lbh); return error; } @@ -1385,7 +1384,7 @@ static int fix_hashtable(struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, log_err(_("Leaf block should start at 0x%x, but it appears at " "0x%x in the hash table.\n"), leaf_proper_start, proper_start); - error = lost_leaf(ip, tbl, leafblk, len, lindex, lbh); + error = lost_leaf(cx, ip, tbl, leafblk, len, lindex, lbh); lgfs2_brelse(lbh); return error; } @@ -1579,7 +1578,7 @@ static int check_hash_tbl_dups(struct lgfs2_inode *ip, __be64 *tbl, * we may need to reference leaf blocks to fix it, which means we need * to check and/or fix a leaf block along the way. */ -static int check_hash_tbl(struct lgfs2_inode *ip, __be64 *tbl, +static int check_hash_tbl(struct fsck_cx *cx, struct lgfs2_inode *ip, __be64 *tbl, unsigned hsize, void *private) { int error = 0; @@ -1660,7 +1659,7 @@ static int check_hash_tbl(struct lgfs2_inode *ip, __be64 *tbl, log_debug(_("lindex 0x%x is not a proper starting " "point for leaf %"PRIu64" (0x%"PRIx64"): 0x%"PRIx32"\n"), lindex, leafblk, leafblk, proper_start); - changes = fix_hashtable(ip, tbl, hsize, leafblk, + changes = fix_hashtable(cx, ip, tbl, hsize, leafblk, lindex, proper_start, len, &proper_len, factor); /* Check if we need to split more leaf blocks */ @@ -1690,7 +1689,7 @@ static int check_hash_tbl(struct lgfs2_inode *ip, __be64 *tbl, leaf.lf_depth > ip->i_depth) leaf.lf_depth = factor; lgfs2_brelse(lbh); - changes = fix_hashtable(ip, tbl, hsize, leafblk, + changes = fix_hashtable(cx, ip, tbl, hsize, leafblk, lindex, lindex, len, &proper_len, leaf.lf_depth); /* If fixing the hash table made changes, we can no @@ -1734,7 +1733,7 @@ static int check_hash_tbl(struct lgfs2_inode *ip, __be64 *tbl, "leaf %"PRIu64" (0x%"PRIx64"): 0x%x\n"), len, leafblk, leafblk, proper_len); - changes = fix_hashtable(ip, tbl, hsize, + changes = fix_hashtable(cx, ip, tbl, hsize, leafblk, lindex, lindex, len, &proper_len, @@ -1763,7 +1762,7 @@ static struct metawalk_fxns pass2_fxns = { .repair_leaf = pass2_repair_leaf, };
-static int check_metalist_qc(struct iptr iptr, struct lgfs2_buffer_head **bh, int h, +static int check_metalist_qc(struct fsck_cx *cx, struct iptr iptr, struct lgfs2_buffer_head **bh, int h, int *is_valid, int *was_duplicate, void *private) { struct lgfs2_inode *ip = iptr.ipt_ip; @@ -1775,7 +1774,7 @@ static int check_metalist_qc(struct iptr iptr, struct lgfs2_buffer_head **bh, in return META_IS_GOOD; }
-static int check_data_qc(struct lgfs2_inode *ip, uint64_t metablock, +static int check_data_qc(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t metablock, uint64_t block, void *private, struct lgfs2_buffer_head *bbh, __be64 *ptr) { @@ -1813,7 +1812,7 @@ static struct metawalk_fxns quota_change_fxns = { * @builder - a rebuild function for the file * * Returns: 0 if all went well, else error. */ -static int check_pernode_for(int x, struct lgfs2_inode *pernode, const char *fn, +static int check_pernode_for(struct fsck_cx *cx, int x, struct lgfs2_inode *pernode, const char *fn, size_t filelen, int multiple, struct metawalk_fxns *pass, int builder(struct lgfs2_inode *per_node, @@ -1845,13 +1844,13 @@ static int check_pernode_for(int x, struct lgfs2_inode *pernode, const char *fn, goto build_it; } if (pass) { - error = check_metatree(ip, pass); + error = check_metatree(cx, ip, pass); if (!error) goto out_good; log_err(_("System file %s has bad contents.\n"), fn); if (!query( _("Delete and rebuild the system file? (y/n) "))) goto out_good; - check_metatree(ip, &pass2_fxns_delete); + check_metatree(cx, ip, &pass2_fxns_delete); fsck_inode_put(&ip); lgfs2_dirent_del(pernode, fn, strlen(fn)); goto build_it; @@ -1907,7 +1906,7 @@ static int build_quota_change(struct lgfs2_inode *per_node, unsigned int n)
/* Check system directory inode */ /* Should work for all system directories: root, master, jindex, per_node */ -static int check_system_dir(struct lgfs2_inode *sysinode, const char *dirname, +static int check_system_dir(struct fsck_cx *cx, struct lgfs2_inode *sysinode, const char *dirname, int builder(struct lgfs2_sbd *sdp)) { uint64_t iblock = 0; @@ -1928,13 +1927,13 @@ static int check_system_dir(struct lgfs2_inode *sysinode, const char *dirname, pass2_fxns.private = (void *) &ds; if (ds.q == GFS2_BLKST_FREE) { /* First check that the directory's metatree is valid */ - error = check_metatree(sysinode, &pass2_fxns); + error = check_metatree(cx, sysinode, &pass2_fxns); if (error < 0) { stack; return error; } } - error = check_dir(sysinode->i_sbd, sysinode, &pass2_fxns); + error = check_dir(cx, sysinode, &pass2_fxns); if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; if (error < 0) { @@ -1944,7 +1943,7 @@ static int check_system_dir(struct lgfs2_inode *sysinode, const char *dirname, if (error > 0) fsck_bitmap_set(sysinode, iblock, dirname, GFS2_BLKST_FREE);
- if (check_inode_eattr(sysinode, &pass2_fxns)) { + if (check_inode_eattr(cx, sysinode, &pass2_fxns)) { stack; return -1; } @@ -1988,13 +1987,13 @@ static int check_system_dir(struct lgfs2_inode *sysinode, const char *dirname, /* Make sure all the per_node files are there, and valid */ for (j = 0; j < sysinode->i_sbd->md.journals; j++) { sprintf(fn, "inum_range%d", j); - error += check_pernode_for(j, sysinode, fn, 16, 0, + error += check_pernode_for(cx, j, sysinode, fn, 16, 0, NULL, build_inum_range); sprintf(fn, "statfs_change%d", j); - error += check_pernode_for(j, sysinode, fn, 24, 0, + error += check_pernode_for(cx, j, sysinode, fn, 24, 0, NULL, build_statfs_change); sprintf(fn, "quota_change%d", j); - error += check_pernode_for(j, sysinode, fn, 1048576, 1, + error += check_pernode_for(cx, j, sysinode, fn, 1048576, 1, "a_change_fxns, build_quota_change); } @@ -2018,14 +2017,14 @@ static inline int is_system_dir(struct lgfs2_sbd *sdp, uint64_t block) return 0; }
-static int pass2_check_dir(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) +static int pass2_check_dir(struct fsck_cx *cx, struct lgfs2_inode *ip) { uint64_t dirblk = ip->i_num.in_addr; struct dir_status ds = {0}; int error;
pass2_fxns.private = &ds; - error = check_dir(sdp, ip, &pass2_fxns); + error = check_dir(cx, ip, &pass2_fxns); if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; if (error < 0) { @@ -2042,7 +2041,7 @@ static int pass2_check_dir(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) } if (query(_("Remove directory entry for bad inode %"PRIu64" (0x%"PRIx64") in %"PRIu64" (0x%"PRIx64")? (y/n)"), dirblk, dirblk, di->treewalk_parent, di->treewalk_parent)) { - error = remove_dentry_from_dir(sdp, di->treewalk_parent, dirblk); + error = remove_dentry_from_dir(cx, di->treewalk_parent, dirblk); if (error < 0) { stack; return FSCK_ERROR; @@ -2057,7 +2056,7 @@ static int pass2_check_dir(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip)
log_debug(_("Directory block %"PRIu64" (0x%"PRIx64") is now marked as 'invalid'\n"), dirblk, dirblk); - check_n_fix_bitmap(sdp, ip->i_rgd, dirblk, 0, GFS2_BLKST_FREE); + check_n_fix_bitmap(cx->sdp, ip->i_rgd, dirblk, 0, GFS2_BLKST_FREE); }
if (!ds.dotdir) { @@ -2067,7 +2066,7 @@ static int pass2_check_dir(struct lgfs2_sbd *sdp, struct lgfs2_inode *ip) if (query( _("Is it okay to add '.' entry? (y/n) "))) { struct lgfs2_inum no = ip->i_num; error = lgfs2_dir_add(ip, ".", 1, &no, - (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR)); + (cx->sdp->gfs1 ? GFS_FILE_DIR : DT_DIR)); if (error) { log_err(_("Error adding directory %s: %s\n"), "'.'", strerror(errno)); @@ -2117,27 +2116,27 @@ int pass2(struct fsck_cx *cx)
/* Check all the system directory inodes. */ if (!sdp->gfs1 && - check_system_dir(sdp->md.jiinode, "jindex", build_jindex)) { + check_system_dir(cx, sdp->md.jiinode, "jindex", build_jindex)) { stack; return FSCK_ERROR; } if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; if (!sdp->gfs1 && - check_system_dir(sdp->md.pinode, "per_node", build_per_node)) { + check_system_dir(cx, sdp->md.pinode, "per_node", build_per_node)) { stack; return FSCK_ERROR; } if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; if (!sdp->gfs1 && - check_system_dir(sdp->master_dir, "master", lgfs2_build_master)) { + check_system_dir(cx, sdp->master_dir, "master", lgfs2_build_master)) { stack; return FSCK_ERROR; } if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; - if (check_system_dir(sdp->md.rooti, "root", lgfs2_build_root)) { + if (check_system_dir(cx, sdp->md.rooti, "root", lgfs2_build_root)) { stack; return FSCK_ERROR; } @@ -2173,7 +2172,7 @@ int pass2(struct fsck_cx *cx) stack; return FSCK_ERROR; } - error = pass2_check_dir(sdp, ip); + error = pass2_check_dir(cx, ip); fsck_inode_put(&ip);
if (skip_this_pass || fsck_abort) diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c index 94d91d19..0495382c 100644 --- a/gfs2/fsck/pass3.c +++ b/gfs2/fsck/pass3.c @@ -54,9 +54,9 @@ static int attach_dotdot_to(struct lgfs2_sbd *sdp, uint64_t newdotdot, return 0; }
-static struct dir_info *mark_and_return_parent(struct lgfs2_sbd *sdp, - struct dir_info *di) +static struct dir_info *mark_and_return_parent(struct fsck_cx *cx, struct dir_info *di) { + struct lgfs2_sbd *sdp = cx->sdp; struct dir_info *pdi; int q_dotdot, q_treewalk; int error = 0; @@ -129,7 +129,7 @@ static struct dir_info *mark_and_return_parent(struct lgfs2_sbd *sdp, log_err( _("Directory entry to invalid inode remains\n")); return NULL; } - error = remove_dentry_from_dir(sdp, di->treewalk_parent, di->dinode.in_addr); + error = remove_dentry_from_dir(cx, di->treewalk_parent, di->dinode.in_addr); if (error < 0) { stack; return NULL; @@ -217,7 +217,7 @@ int pass3(struct fsck_cx *cx) * param */ if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; - tdi = mark_and_return_parent(sdp, di); + tdi = mark_and_return_parent(cx, di);
if (tdi) { log_debug(_("Directory at block %"PRIu64" (0x%"PRIx64") connected\n"), diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c index 5862ca0f..b3441cf9 100644 --- a/gfs2/fsck/pass4.c +++ b/gfs2/fsck/pass4.c @@ -49,9 +49,10 @@ static int fix_link_count(uint32_t counted_links, struct lgfs2_inode *ip) * * Returns: 1 if caller should do "continue", 0 if not. */ -static int handle_unlinked(struct lgfs2_sbd *sdp, uint64_t no_addr, +static int handle_unlinked(struct fsck_cx *cx, uint64_t no_addr, uint32_t *counted_links, int *lf_addition) { + struct lgfs2_sbd *sdp = cx->sdp; struct lgfs2_inode *ip; int q;
@@ -63,8 +64,8 @@ static int handle_unlinked(struct lgfs2_sbd *sdp, uint64_t no_addr, no_addr, no_addr); if (query(_("Delete unlinked inode with bad blocks? (y/n) "))) { ip = fsck_load_inode(sdp, no_addr); - check_inode_eattr(ip, &pass4_fxns_delete); - check_metatree(ip, &pass4_fxns_delete); + check_inode_eattr(cx, ip, &pass4_fxns_delete); + check_metatree(cx, ip, &pass4_fxns_delete); fsck_bitmap_set(ip, no_addr, _("bad unlinked"), GFS2_BLKST_FREE); fsck_inode_put(&ip); @@ -78,8 +79,8 @@ static int handle_unlinked(struct lgfs2_sbd *sdp, uint64_t no_addr, no_addr, no_addr, q); ip = fsck_load_inode(sdp, no_addr); if (query(_("Delete unlinked inode? (y/n) "))) { - check_inode_eattr(ip, &pass4_fxns_delete); - check_metatree(ip, &pass4_fxns_delete); + check_inode_eattr(cx, ip, &pass4_fxns_delete); + check_metatree(cx, ip, &pass4_fxns_delete); fsck_bitmap_set(ip, no_addr, _("invalid unlinked"), GFS2_BLKST_FREE); fsck_inode_put(&ip); @@ -160,8 +161,9 @@ static int adjust_lf_links(int lf_addition) return 0; }
-static int scan_inode_list(struct lgfs2_sbd *sdp) +static int scan_inode_list(struct fsck_cx *cx) { + struct lgfs2_sbd *sdp = cx->sdp; struct osi_node *tmp, *next = NULL; struct inode_info *ii; int lf_addition = 0; @@ -180,7 +182,7 @@ static int scan_inode_list(struct lgfs2_sbd *sdp) (ii->num.in_addr == sdp->md.statfs->i_num.in_addr))) continue; if (ii->counted_links == 0) { - if (handle_unlinked(sdp, ii->num.in_addr, + if (handle_unlinked(cx, ii->num.in_addr, &ii->counted_links, &lf_addition)) continue; } /* if (ii->counted_links == 0) */ @@ -195,8 +197,9 @@ static int scan_inode_list(struct lgfs2_sbd *sdp) return adjust_lf_links(lf_addition); }
-static int scan_dir_list(struct lgfs2_sbd *sdp) +static int scan_dir_list(struct fsck_cx *cx) { + struct lgfs2_sbd *sdp = cx->sdp; struct osi_node *tmp, *next = NULL; struct dir_info *di; int lf_addition = 0; @@ -213,7 +216,7 @@ static int scan_dir_list(struct lgfs2_sbd *sdp) di->dinode.in_addr == sdp->md.jiinode->i_num.in_addr) continue; if (di->counted_links == 0) { - if (handle_unlinked(sdp, di->dinode.in_addr, + if (handle_unlinked(cx, di->dinode.in_addr, &di->counted_links, &lf_addition)) continue; } else if (di->di_nlink != di->counted_links) { @@ -227,7 +230,7 @@ static int scan_dir_list(struct lgfs2_sbd *sdp) return adjust_lf_links(lf_addition); }
-static int scan_nlink1_list(struct lgfs2_sbd *sdp) +static int scan_nlink1_list(struct fsck_cx *cx) { uint64_t blk; uint32_t counted_links; @@ -245,8 +248,7 @@ static int scan_nlink1_list(struct lgfs2_sbd *sdp) to lost+found. In this case, however, there's not a real count, so we fake it out to be 1. */ counted_links = 1; - if (handle_unlinked(sdp, blk, &counted_links, - &lf_addition)) + if (handle_unlinked(cx, blk, &counted_links, &lf_addition)) continue; } } @@ -264,23 +266,21 @@ static int scan_nlink1_list(struct lgfs2_sbd *sdp) */ int pass4(struct fsck_cx *cx) { - struct lgfs2_sbd *sdp = cx->sdp; - if (lf_dip) log_debug( _("At beginning of pass4, lost+found entries is %u\n"), lf_dip->i_entries); log_info( _("Checking inode reference counts: multi-links.\n")); - if (scan_inode_list(sdp)) { + if (scan_inode_list(cx)) { stack; return FSCK_ERROR; } log_info( _("Checking inode reference counts: directories.\n")); - if (scan_dir_list(sdp)) { + if (scan_dir_list(cx)) { stack; return FSCK_ERROR; } log_info( _("Checking inode reference counts: normal links.\n")); - if (scan_nlink1_list(sdp)) { + if (scan_nlink1_list(cx)) { stack; return FSCK_ERROR; } diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index 2a8c0eaa..8ce1a32d 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -510,8 +510,9 @@ static uint64_t hunt_and_peck(struct lgfs2_sbd *sdp, uint64_t blk, * from gfs1 to gfs2 after a gfs_grow operation. In that case, the rgrps * will not be on predictable boundaries. */ -static int rindex_rebuild(struct lgfs2_sbd *sdp, int *num_rgs, int gfs_grow) +static int rindex_rebuild(struct fsck_cx *cx, int *num_rgs, int gfs_grow) { + struct lgfs2_sbd *sdp = cx->sdp; struct osi_node *n, *next = NULL; struct lgfs2_buffer_head *bh; uint64_t rg_dist[MAX_RGSEGMENTS] = {0, }; @@ -532,7 +533,7 @@ static int rindex_rebuild(struct lgfs2_sbd *sdp, int *num_rgs, int gfs_grow) * To make matters worse, journals may span several (small) rgrps, * so we can't go by the rgrps. */ - if (init_jindex(sdp, 0) != 0) { + if (init_jindex(cx, 0) != 0) { log_crit(_("Error: Can't read jindex required for rindex " "repairs.\n")); return -1; @@ -943,8 +944,9 @@ static int expect_rindex_sanity(struct lgfs2_sbd *sdp, int *num_rgs) * was converted from GFS via gfs2_convert, and its rgrps are * not on nice boundaries thanks to previous gfs_grow ops. Lovely. */ -int rindex_repair(struct lgfs2_sbd *sdp, int trust_lvl, int *ok) +int rindex_repair(struct fsck_cx *cx, int trust_lvl, int *ok) { + struct lgfs2_sbd *sdp = cx->sdp; struct osi_node *n, *next = NULL, *e, *enext; int error, discrepancies, percent; int calc_rg_count = 0, rg; @@ -980,7 +982,7 @@ int rindex_repair(struct lgfs2_sbd *sdp, int trust_lvl, int *ok) /* Free previous incarnations in memory, if any. */ lgfs2_rgrp_free(sdp, &sdp->rgtree);
- error = rindex_rebuild(sdp, &calc_rg_count, 0); + error = rindex_rebuild(cx, &calc_rg_count, 0); if (error) { log_crit( _("Error rebuilding rgrp list.\n")); lgfs2_rgrp_free(sdp, &rgcalc); @@ -990,7 +992,7 @@ int rindex_repair(struct lgfs2_sbd *sdp, int trust_lvl, int *ok) /* Free previous incarnations in memory, if any. */ lgfs2_rgrp_free(sdp, &sdp->rgtree);
- error = rindex_rebuild(sdp, &calc_rg_count, 1); + error = rindex_rebuild(cx, &calc_rg_count, 1); if (error) { log_crit( _("Error rebuilding rgrp list.\n")); lgfs2_rgrp_free(sdp, &rgcalc); diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c index 9e5608a3..5dafcf9e 100644 --- a/gfs2/fsck/util.c +++ b/gfs2/fsck/util.c @@ -21,7 +21,7 @@ const char *reftypes[REF_TYPES + 1] = {"data", "metadata", "an extended attribute", "an inode", "unimportant"};
-void big_file_comfort(struct lgfs2_inode *ip, uint64_t blks_checked) +void big_file_comfort(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t blks_checked) { static struct timeval tv; static uint32_t seconds = 0; diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h index f63a8af1..5742f96f 100644 --- a/gfs2/fsck/util.h +++ b/gfs2/fsck/util.h @@ -10,7 +10,7 @@ #define INODE_INVALID 0
struct di_info *search_list(osi_list_t *list, uint64_t addr); -void big_file_comfort(struct lgfs2_inode *ip, uint64_t blks_checked); +void big_file_comfort(struct fsck_cx *cx, struct lgfs2_inode *ip, uint64_t blks_checked); void display_progress(uint64_t block); int add_duplicate_ref(struct lgfs2_inode *ip, uint64_t block, enum dup_ref_type reftype, int first, int inode_valid);