Gitweb:
http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=bcd5202a...
Commit: bcd5202ac5c8b8165b8005a572b9af1f208c34f1
Parent: 99444c0388a31db2a579c63ea5ddb5333a3ffe06
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 13 14:42:14 2017 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jan 16 15:43:23 2017 -0500
fsck.gfs2: Repair rindex entries that were destroyed
If an rindex entry was destroyed, the rindex was skipped, which
means its rgrp never gets inserted into the rgrp tree. The trouble
is, that causes a off-by-one-entry problem with all subsequent
rindex entries. So if rindex entry R is destroyed, then rebuilt,
originally good entry R+1 is checked against new entry for R.
Function rg_repair already had the capability to insert new rindex
entries, but only at the end. This would be typical for a gfs2_grow
that failed and left a bunch of rgrps on the device, but the rindex
was never synced properly.
This patch allows the function to insert catch-up entries in the
middle, which re-syncs the actual versus expected rgrp trees.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/rgrepair.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 49bbad6..f397db1 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -1137,10 +1137,14 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
int *sane)
next = osi_next(n);
enext = osi_next(e);
expected = (struct rgrp_tree *)e;
+ actual = (struct rgrp_tree *)n;
- /* If we ran out of actual rindex entries due to rindex
+ /* If the next "actual" rgrp in memory is too far away,
+ fill in a new one with the expected value. -or-
+ If we ran out of actual rindex entries due to rindex
damage, fill in a new one with the expected values. */
- if (!n) { /* end of actual rindex */
+ if (!n || /* end of actual rindex */
+ expected->ri.ri_addr < actual->ri.ri_addr) {
log_err( _("Entry missing from rindex: 0x%llx\n"),
(unsigned long long)expected->ri.ri_addr);
actual = rgrp_insert(&sdp->rgtree,
@@ -1150,8 +1154,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
int *sane)
break;
}
rindex_modified = 1;
+ next = n; /* Ensure that the old actual gets checked
+ against a new expected, since we added */
} else {
- actual = (struct rgrp_tree *)n;
ri_compare(rg, actual->ri, expected->ri, ri_addr,
"llx", unsigned long long);
ri_compare(rg, actual->ri, expected->ri, ri_length,