Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 152593 Details for
Bug 223893
gfs2_fsck unable to fix damaged RGs and RG indexes.
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
First go at a fix
223893.patch.try1 (text/plain), 21.28 KB, created by
Robert Peterson
on 2007-04-13 21:37:37 UTC
(
hide
)
Description:
First go at a fix
Filename:
MIME Type:
Creator:
Robert Peterson
Created:
2007-04-13 21:37:37 UTC
Size:
21.28 KB
patch
obsolete
>Index: Makefile >=================================================================== >RCS file: /cvs/cluster/cluster/gfs2/fsck/Makefile,v >retrieving revision 1.7 >diff -w -u -p -u -p -r1.7 Makefile >--- Makefile 23 Jan 2007 20:55:46 -0000 1.7 >+++ Makefile 13 Apr 2007 14:16:13 -0000 >@@ -22,7 +22,7 @@ LIBS=${top_srcdir}/libgfs2 > .PHONY: all clean > > sources = main.c initialize.c pass1.c pass1b.c pass1c.c pass2.c pass3.c \ >- pass4.c pass5.c util.c fs_recovery.c \ >+ pass4.c pass5.c util.c fs_recovery.c rgrepair.c\ > lost_n_found.c link.c eattr.c hash.c inode_hash.c metawalk.c > > CFLAGS+=-D_FILE_OFFSET_BITS=64 -DHELPER_PROGRAM -DGFS_RELEASE_NAME=\"${RELEASE}\" -Wall -O2 >Index: fsck.h >=================================================================== >RCS file: /cvs/cluster/cluster/gfs2/fsck/fsck.h,v >retrieving revision 1.4 >diff -w -u -p -u -p -r1.4 fsck.h >--- fsck.h 23 Jan 2007 19:23:07 -0000 1.4 >+++ fsck.h 13 Apr 2007 14:16:13 -0000 >@@ -38,6 +38,17 @@ struct dir_info > > }; > >+enum rgindex_trust_level { /* how far can we trust our RG index? */ >+ blind_faith = 0, /* We'd like to trust the rgindex. We always used to >+ before bz 179069. This should cover most cases. */ >+ open_minded = 1, /* At least 1 RG is corrupt. Try to calculate what it >+ should be, in a perfect world where our RGs are all >+ on even boundaries. Blue sky. Chirping birds. */ >+ distrust = 2 /* The world isn't perfect, our RGs are not on nice neat >+ boundaries. The fs must have been messed with by >+ gfs_grow or something. Count the RGs by hand. */ >+}; >+ > int initialize(struct gfs2_sbd *sbp); > void destroy(struct gfs2_sbd *sbp); > int block_mounters(struct gfs2_sbd *sbp, int block_em); >@@ -48,6 +59,7 @@ int pass2(struct gfs2_sbd *sbp); > int pass3(struct gfs2_sbd *sbp); > int pass4(struct gfs2_sbd *sbp); > int pass5(struct gfs2_sbd *sbp); >+int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count); > > /* FIXME: Hack to get this going for pass2 - this should be pulled out > * of pass1 and put somewhere else... */ >Index: initialize.c >=================================================================== >RCS file: /cvs/cluster/cluster/gfs2/fsck/initialize.c,v >retrieving revision 1.7 >diff -w -u -p -u -p -r1.7 initialize.c >--- initialize.c 23 Jan 2007 19:23:07 -0000 1.7 >+++ initialize.c 13 Apr 2007 14:16:13 -0000 >@@ -204,6 +204,7 @@ static int fill_super_block(struct gfs2_ > struct gfs2_statfs_change sc; > int rgcount; > uint64_t addl_mem_needed; >+ enum rgindex_trust_level trust_lvl; > > sync(); > >@@ -284,11 +285,25 @@ static int fill_super_block(struct gfs2_ > return -1; > } > >- if(ri_update(sdp, &rgcount)){ >- log_err("Unable to fill in resource group information.\n"); >+ log_info("Validating Resource Group index.\n"); >+ for (trust_lvl = blind_faith; trust_lvl <= distrust; trust_lvl++) { >+ log_info("Level %d check.\n", trust_lvl + 1); >+ if(ri_update(sdp, &rgcount) == 0) { >+ log_err("(passed)\n"); >+ break; >+ } >+ else { >+ if (!rg_repair(sdp, trust_lvl + 1, &rgcount)) { >+ log_err("(passed)\n"); >+ break; >+ } >+ } >+ } >+ if (trust_lvl > distrust) { >+ log_err("(failed--recovery impossible)\n"); > goto fail; > } >- >+ log_info("%u resource groups found.\n", rgcount); > /******************************************************************* > ******* Now, set boundary fields in the super block ************* > *******************************************************************/ >Index: rgrepair.c >=================================================================== >RCS file: rgrepair.c >diff -N rgrepair.c >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ rgrepair.c 13 Apr 2007 14:16:13 -0000 >@@ -0,0 +1,459 @@ >+/****************************************************************************** >+******************************************************************************* >+** >+** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. >+** Copyright (C) 2007 Red Hat, Inc. All rights reserved. >+** >+** This copyrighted material is made available to anyone wishing to use, >+** modify, copy, or redistribute it subject to the terms and conditions >+** of the GNU General Public License v.2. >+** >+******************************************************************************* >+******************************************************************************/ >+ >+#include <unistd.h> >+#include <inttypes.h> >+#include <stdio.h> >+#include <stdint.h> >+#include <stdlib.h> >+#include <string.h> >+#include <errno.h> >+ >+#include "libgfs2.h" >+#include "osi_list.h" >+#include "fsck.h" >+ >+int rgindex_modified = FALSE; >+ >+#define ri_equal(ondisk, expected, field) (ondisk.field == expected.field) >+ >+#define ri_compare(rg, ondisk, expected, field, fmt) \ >+ if (ondisk.field != expected.field) { \ >+ log_warn("rgindex #%d " #field " discrepancy: index 0x%" fmt \ >+ " != expected: 0x%" fmt "\n", \ >+ rg + 1, ondisk.field, expected.field); \ >+ ondisk.field = expected.field; \ >+ rgindex_modified = TRUE; \ >+ } >+ >+/* >+ * gfs2_rgindex_rebuild - rebuild a corrupt Resource Group (RG) index manually >+ * where trust_lvl == distrust >+ * >+ * If this routine is called, it means we have RGs in odd/unexpected places, >+ * and there is a corrupt RG. In other words, we can't trust the RG index >+ * is completely sane, and the RGs don't fit on nice neat fs boundaries. >+ * So we have no choice but to go through the count them by hand. >+ * We've tried twice to recover the RGs and RG index, and failed. This is >+ * our last chance to remedy the situation. >+ * >+ * This routine tries to minimize performance impact by: >+ * 1. Skipping through the filesystem at known increments when possible. >+ * 2. Shuffle through every block when RGs are not found at the predicted >+ * locations. >+ * >+ * Note: A GFS2 filesystem differs from a GFS1 file system in that there will >+ * only be ONE device, divided into evenly-spaced RGs. The journals and even >+ * the rgindex are kept as part of the file system, so it's imparative that >+ * we can rebuild it by hand. If the file system has been extended with >+ * gfs2_grow the RGs won't be in predictable places after a while. >+ * That makes like both easy and difficult. Easy because the RGs are all >+ * predictable until you get to an extension. Difficult because you can't >+ * predict whether a missing RG is gone because the file system is corrupt >+ * or because it's just been extended and therefore in another location. >+ * >+ */ >+int gfs2_rgindex_rebuild(struct gfs2_sbd *sdp, int *num_rgs) >+{ >+ struct gfs2_buffer_head *bh; >+ uint64_t shortest_dist_btwn_rgs; >+ uint64_t blk, block_of_last_rg; >+ uint64_t fwd_block, block_bump; >+ uint64_t first_rg_dist, initial_first_rg_dist; >+ struct rgrp_list *calc_rgd, *prev_rgd; >+ int number_of_rgs; >+ struct gfs2_rindex buf, tmpndx; >+ int rg_was_fnd = FALSE, corrupt_rgs = 0, bitmap_was_fnd; >+ >+ number_of_rgs = 0; >+ initial_first_rg_dist = first_rg_dist = sdp->sb_addr + 1; >+ block_of_last_rg = sdp->sb_addr + 1; >+ /* ------------------------------------------------------------- */ >+ /* First, hunt and peck for the shortest distance between RGs. */ >+ /* Sample several of them because an RG that's been blasted will */ >+ /* look like twice the distance. */ >+ /* ------------------------------------------------------------- */ >+ shortest_dist_btwn_rgs = sdp->device.length; >+ for (blk = sdp->sb_addr + 1; >+ blk < sdp->device.length && number_of_rgs < 6; >+ blk++) { >+ bh = bread(sdp, blk); >+ if ((blk == sdp->sb_addr + 1) || >+ (!gfs2_check_meta(bh, GFS2_METATYPE_RG))) { >+ log_debug("RG found at block 0x%" PRIx64 "\n", blk); >+ if (blk > sdp->sb_addr + 1) { >+ uint64_t rgdist; >+ >+ rgdist = blk - block_of_last_rg; >+ log_debug("dist 0x%" PRIx64 " = 0x% " PRIx64 >+ " - 0x%" PRIx64, rgdist, >+ blk, block_of_last_rg); >+ /* ----------------------------------------- */ >+ /* We found an RG. Check to see if we need */ >+ /* to set the first_rg_dist based on whether */ >+ /* it's still at its initial value (i.e. the */ >+ /* fs. The first rg distance is different */ >+ /* from the rest because of the superblock */ >+ /* and 64K dead space. */ >+ /* ----------------------------------------- */ >+ if (first_rg_dist == initial_first_rg_dist) >+ first_rg_dist = rgdist; >+ if (rgdist < shortest_dist_btwn_rgs) { >+ shortest_dist_btwn_rgs = rgdist; >+ log_debug("(shortest so far)\n"); >+ } >+ else >+ log_debug("\n"); >+ } >+ block_of_last_rg = blk; >+ number_of_rgs++; >+ } >+ brelse(bh, not_updated); >+ } >+ number_of_rgs = 0; >+ /* -------------------------------------------------------------- */ >+ /* Sanity-check our first_rg_dist. If RG #2 got nuked, the */ >+ /* first_rg_dist would measure from #1 to #3, which would be bad. */ >+ /* We need to take remedial measures to fix it (from the index). */ >+ /* -------------------------------------------------------------- */ >+ log_debug("First RG distance: 0x%" PRIx64 "\n", first_rg_dist); >+ log_debug("Distance between RGs: 0x%" PRIx64 "\n", >+ shortest_dist_btwn_rgs); >+ if (first_rg_dist >= shortest_dist_btwn_rgs + >+ (shortest_dist_btwn_rgs / 4)) { >+ /* read in the second RG index entry for this subd. */ >+ gfs2_readi(sdp->md.riinode, (char *)&buf, >+ sizeof(struct gfs2_rindex), >+ sizeof(struct gfs2_rindex)); >+ gfs2_rindex_in(&tmpndx, (char *)&buf); >+ if (tmpndx.ri_addr > sdp->sb_addr + 1) { /* sanity check */ >+ log_warn("RG 2 is damaged: getting dist from index: "); >+ first_rg_dist = tmpndx.ri_addr - (sdp->sb_addr + 1); >+ log_warn("0x%" PRIx64 "\n", first_rg_dist); >+ } >+ else { >+ log_warn("RG index 2 is damaged: extrapolating dist: "); >+ first_rg_dist = sdp->device.length - >+ (sdp->rgrps - 1) * >+ (sdp->device.length / sdp->rgrps); >+ log_warn("0x%" PRIx64 "\n", first_rg_dist); >+ } >+ log_debug("Adjusted first RG distance: 0x%" PRIx64 "\n", >+ first_rg_dist); >+ } /* if first RG distance is within tolerance */ >+ /* -------------------------------------------------------------- */ >+ /* Now go through the RGs and verify their integrity, fixing as */ >+ /* needed when corruption is encountered. */ >+ /* -------------------------------------------------------------- */ >+ prev_rgd = NULL; >+ block_bump = first_rg_dist; >+ for (blk = sdp->sb_addr + 1; blk <= sdp->device.length; >+ blk += block_bump) { >+ log_debug("Block 0x%" PRIx64 "\n", blk); >+ bh = bread(sdp, blk); >+ rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG)); >+ brelse(bh, not_updated); >+ /* Allocate a new RG and index. */ >+ calc_rgd = malloc(sizeof(struct rgrp_list)); >+ memset(calc_rgd, 0, sizeof(struct rgrp_list)); >+ osi_list_add_prev(&calc_rgd->list, &sdp->rglist); >+ calc_rgd->ri.ri_length = 1; >+ calc_rgd->ri.ri_addr = blk; >+ if (!rg_was_fnd) { /* if not an RG */ >+ /* ------------------------------------------------- */ >+ /* This SHOULD be an RG but isn't. */ >+ /* ------------------------------------------------- */ >+ corrupt_rgs++; >+ if (corrupt_rgs < 5) >+ log_debug("Missing or damaged RG at block %" >+ PRIu64 " (0x%" PRIx64 ")\n", >+ blk, blk); >+ else { >+ log_crit("Error: too many bad RGs.\n"); >+ return -1; >+ } >+ } >+ /* ------------------------------------------------ */ >+ /* Now go through and count the bitmaps for this RG */ >+ /* ------------------------------------------------ */ >+ bitmap_was_fnd = FALSE; >+ for (fwd_block = blk + 1; >+ fwd_block < sdp->device.length; >+ fwd_block++) { >+ bh = bread(sdp, fwd_block); >+ bitmap_was_fnd = >+ (!gfs2_check_meta(bh, GFS2_METATYPE_RB)); >+ brelse(bh, not_updated); >+ if (bitmap_was_fnd) /* if a bitmap */ >+ calc_rgd->ri.ri_length++; >+ else >+ break; /* end of bitmap, so call it quits. */ >+ } /* for subsequent bitmaps */ >+ calc_rgd->ri.ri_data0 = calc_rgd->ri.ri_addr + >+ calc_rgd->ri.ri_length; >+ if (prev_rgd) { >+ uint32_t rgblocks, bitblocks; >+ >+ rgblocks = block_bump; >+ rgblocks2bitblocks(sdp->bsize, &rgblocks, &bitblocks); >+ >+ prev_rgd->ri.ri_addr = blk; >+ prev_rgd->ri.ri_length = bitblocks; >+ prev_rgd->ri.ri_data0 = blk + bitblocks; >+ prev_rgd->ri.ri_bitbytes = rgblocks / GFS2_NBBY; >+ >+ prev_rgd->ri.ri_data = block_bump - rgblocks; >+ prev_rgd->ri.ri_data -= prev_rgd->ri.ri_data % >+ GFS2_NBBY; >+ prev_rgd->ri.ri_bitbytes = prev_rgd->ri.ri_data / >+ GFS2_NBBY; >+ log_debug("Prev ri_data set to: %" PRIx32 ".\n", >+ prev_rgd->ri.ri_data); >+ } >+ number_of_rgs++; >+ log_warn("%c RG %d at block 0x%" PRIX64 " %s", >+ (rg_was_fnd ? ' ' : '*'), number_of_rgs, blk, >+ (rg_was_fnd ? "intact" : "*** DAMAGED ***")); >+ prev_rgd = calc_rgd; >+ block_of_last_rg = blk; >+ >+ if (blk == sdp->sb_addr + 1) >+ block_bump = first_rg_dist; >+ else >+ block_bump = shortest_dist_btwn_rgs; >+ if (block_bump != 1) >+ log_warn(" [length 0x%" PRIx64 "]\n", block_bump); >+ } /* for each rg block */ >+ *num_rgs = number_of_rgs; >+ return 0; >+} >+ >+/* >+ * gfs2_rgindex_calculate - calculate what the rgindex should look like >+ * in a perfect world (trust_lvl == open_minded) >+ * >+ * Calculate what the rgindex should look like, >+ * so we can later check if all RG index entries are sane. >+ * This is a lot easier for gfs2 because we can just call the same libgfs2 >+ * functions used by mkfs. >+ * >+ * Returns: 0 on success, -1 on failure >+ * Sets: sdp->rglist to a linked list of fsck_rgrp structs representing >+ * what we think the rgindex should really look like. >+ */ >+int gfs2_rgindex_calculate(struct gfs2_sbd *sdp, int *num_rgs) >+{ >+ osi_list_init(&sdp->rglist); >+ sdp->rgsize = GFS2_DEFAULT_RGSIZE; /* compute_rgrp_layout adjusts */ >+ device_geometry(sdp); >+ fix_device_geometry(sdp); >+ /* Compute the default resource group layout as mkfs would have done */ >+ compute_rgrp_layout(sdp, FALSE); >+ build_rgrps(sdp, FALSE); /* FALSE = calc but don't write to disk. */ >+ *num_rgs = 0; >+ log_debug("fs_total_size = 0x%" PRIX64 " blocks.\n", >+ sdp->device.length); >+ /* ----------------------------------------------------------------- */ >+ /* Calculate how many RGs there are supposed to be based on the */ >+ /* rgindex filesize. Remember that our trust level is open-minded */ >+ /* here. If the filesize of the rgindex file is not a multiple of */ >+ /* our rgindex structures, then something's wrong and we can't trust */ >+ /* the index. */ >+ /* ----------------------------------------------------------------- */ >+ *num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex); >+ log_warn("number of rgs in the index = %d.\n", *num_rgs); >+ return 0; >+} >+ >+/* >+ * rewrite_rg_block - rewrite ("fix") a buffer with rg or bitmap data >+ * returns: 0 if the rg was repaired, otherwise 1 >+ */ >+int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg, >+ uint64_t errblock) >+{ >+ int x = errblock - rg->ri.ri_addr; >+ >+ log_err("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither" >+ " GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n", >+ rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr, >+ (int)x+1, (int)rg->ri.ri_length); >+ if (query(&opts, "Fix the RG? (y/n)")) { >+ >+ log_err("Attempting to repair the RG.\n"); >+ rg->bh[x] = bread(sdp, rg->ri.ri_addr + x); >+ if (x) { >+ struct gfs2_meta_header mh; >+ >+ mh.mh_magic = GFS2_MAGIC; >+ mh.mh_type = GFS2_METATYPE_RB; >+ mh.mh_format = GFS2_FORMAT_RB; >+ gfs2_meta_header_out(&mh, rg->bh[x]->b_data); >+ } else { >+ memset(&rg->rg, 0, sizeof(struct gfs2_rgrp)); >+ rg->rg.rg_header.mh_magic = GFS2_MAGIC; >+ rg->rg.rg_header.mh_type = GFS2_METATYPE_RG; >+ rg->rg.rg_header.mh_format = GFS2_FORMAT_RG; >+ rg->rg.rg_free = rg->ri.ri_data; >+ gfs2_rgrp_out(&rg->rg, rg->bh[x]->b_data); >+ } >+ brelse(rg->bh[x], updated); >+ return 0; >+ } >+ return 1; >+} >+ >+/* >+ * rg_repair - try to repair a damaged rg index >+ * trust_lvl - This is how much we trust the rgindex file. >+ * open_minded means it might be okay, but we should verify it. >+ * distrust means it's not to be trusted, so we should go to >+ * greater lengths to build it from scratch. >+ */ >+int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count) >+{ >+ int error, descrepencies; >+ osi_list_t expected_rglist; >+ int calc_rg_count, rgcount_from_index, rg; >+ osi_list_t *exp, *act; /* expected, actual */ >+ struct gfs2_rindex buf; >+ >+ if (trust_lvl == open_minded) { /* If we can't trust RG index */ >+ /* Calculate our own RG index for comparison */ >+ error = gfs2_rgindex_calculate(sdp, &calc_rg_count); >+ if (error) { /* If calculated RGs don't match the fs */ >+ log_info("(failed--trying again at level 3)\n"); >+ gfs2_rgrp_free(sdp, not_updated); >+ return -1; >+ } >+ } >+ else if (trust_lvl == distrust) { /* If we can't trust RG index */ >+ error = gfs2_rgindex_rebuild(sdp, &calc_rg_count); >+ if (error) { /* If calculated RGs don't match the fs */ >+ log_info("(failed--giving up)\n"); >+ return -1; >+ } >+ } >+ /* Move the calculated linked rglist out of the sdp to "expected": */ >+ expected_rglist.next = sdp->rglist.next; >+ expected_rglist.prev = sdp->rglist.prev; >+ sdp->rglist.next->prev = &expected_rglist; >+ sdp->rglist.prev->next = &expected_rglist; >+ /* Read in the rgindex */ >+ osi_list_init(&sdp->rglist); /* Just to be safe */ >+ rindex_read(sdp, &rgcount_from_index); >+ if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) { >+ log_warn("WARNING: rgindex file is corrupt.\n"); >+ return -1; >+ } >+ log_warn("number of rgs expected = %d.\n", sdp->rgrps); >+ if (calc_rg_count != sdp->rgrps) { >+ log_warn("They don't match; either the fs was extended or we have a corrupt index.\n"); >+ return -1; >+ } >+ /* ------------------------------------------------------------- */ >+ /* Now compare the rgindex to what we think it should be. */ >+ /* See how far off our expected values are. If too much, abort. */ >+ /* The theory is: if we calculated the index to have 32 RGs and */ >+ /* we have a large number that are completely wrong, we should */ >+ /* abandon this method of recovery and try a better one. */ >+ /* ------------------------------------------------------------- */ >+ descrepencies = 0; >+ for (rg = 0, act = sdp->rglist.next, exp = expected_rglist.next; >+ act != &sdp->rglist && exp != &expected_rglist; >+ act = act->next, exp = exp->next, rg++) { >+ struct rgrp_list *expected, *actual; >+ >+ expected = osi_list_entry(exp, struct rgrp_list, list); >+ actual = osi_list_entry(act, struct rgrp_list, list); >+ if (!ri_equal(actual->ri, expected->ri, ri_addr) || >+ !ri_equal(actual->ri, expected->ri, ri_length) || >+ !ri_equal(actual->ri, expected->ri, ri_data0) || >+ !ri_equal(actual->ri, expected->ri, ri_data) || >+ !ri_equal(actual->ri, expected->ri, ri_bitbytes)) { >+ descrepencies++; >+ } >+ } >+ if (trust_lvl < distrust && descrepencies > (trust_lvl * 8)) { >+ log_warn("Level %d didn't work. Too many descepencies.\n", >+ trust_lvl); >+ log_warn("%d out of %d RGs did not match what was expected.\n", >+ descrepencies, rg); >+ gfs2_rgrp_free(sdp, not_updated); >+ return -1; >+ } >+ /* ------------------------------------------------------------- */ >+ /* Now compare the rgindex to what we think it should be. */ >+ /* Our rgindex should be pretty predictable unless we've grown */ >+ /* so look for index problems first before looking at the rgs. */ >+ /* ------------------------------------------------------------- */ >+ for (rg = 0, act = sdp->rglist.next, exp = expected_rglist.next; >+ act != &sdp->rglist && exp != &expected_rglist; >+ act = act->next, exp = exp->next, rg++) { >+ struct rgrp_list *expected, *actual; >+ >+ expected = osi_list_entry(exp, struct rgrp_list, list); >+ actual = osi_list_entry(act, struct rgrp_list, list); >+ ri_compare(rg, actual->ri, expected->ri, ri_addr, PRIx64); >+ ri_compare(rg, actual->ri, expected->ri, ri_length, PRIx32); >+ ri_compare(rg, actual->ri, expected->ri, ri_data0, PRIx64); >+ ri_compare(rg, actual->ri, expected->ri, ri_data, PRIx32); >+ ri_compare(rg, actual->ri, expected->ri, ri_bitbytes, >+ PRIx32); >+ /* If we modified the index, write it back to disk. */ >+ if (rgindex_modified) { >+ if (query(&opts, "Fix the index? (y/n)")) { >+ gfs2_rindex_out(&expected->ri, (char *)&buf); >+ gfs2_writei(sdp->md.riinode, (char *)&buf, >+ rg * sizeof(struct gfs2_rindex), >+ sizeof(struct gfs2_rindex)); >+ } >+ else >+ log_err("RG index not fixed.\n"); >+ rgindex_modified = FALSE; >+ } >+ } >+ /* ------------------------------------------------------------- */ >+ /* Read the real RGs and check their integrity. */ >+ /* Now we can somewhat trust the rgindex and the RG addresses, */ >+ /* so let's read them in, check them and optionally fix them. */ >+ /* ------------------------------------------------------------- */ >+ for (rg = 0, act = sdp->rglist.next; act != &sdp->rglist; >+ act = act->next, rg++) { >+ struct rgrp_list *rgd; >+ uint64_t prev_err = 0, errblock; >+ int i; >+ >+ /* Now we try repeatedly to read in the rg. For every block */ >+ /* we encounter that has errors, repair it and try again. */ >+ i = 0; >+ do { >+ rgd = osi_list_entry(act, struct rgrp_list, list); >+ errblock = gfs2_rgrp_read(sdp, rgd); >+ if (errblock) { >+ if (errblock == prev_err) >+ break; >+ prev_err = errblock; >+ rewrite_rg_block(sdp, rgd, errblock); >+ } >+ else { >+ gfs2_rgrp_relse(rgd, not_updated); >+ break; >+ } >+ i++; >+ } while (i < rgd->ri.ri_length); >+ } >+ *rg_count = rg; >+ /* TODO: cleanup and delete the linked lists */ >+ return 0; >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 223893
:
152593
|
153017
|
153868
|
153876