cluster: RHEL6 - fsck.gfs2: link dinodes that only have extended attribute problems

Bob Peterson rpeterso at fedoraproject.org
Tue May 21 12:23:32 UTC 2013


Gitweb:        http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=7b98f01103283f5d925b03d643999b93617299c6
Commit:        7b98f01103283f5d925b03d643999b93617299c6
Parent:        7467be5dc58d4b71281666f365fd01fde91e87fd
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Fri Mar 8 11:50:56 2013 -0700
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri May 17 15:16:51 2013 -0500

fsck.gfs2: link dinodes that only have extended attribute problems

The job of pass1b is to resolve duplicate references to the same block.
Eventually it does a fair job of determining the rightful owner of the
block, and then it has to deal with the other dinode(s) that referenced
the block improperly. If another dinode improperly referenced the block
as data or metadata, it's obvious file corruption and the dinode should
be deleted. However, if the other dinode improperly referenced the
block as an extended attribute, it can fix the situation by removing
the extended attributes from the dinode. Prior to this patch, there
was a check in the code for this situation so that the dinode was only
deleted if the bad block reference was as data or metadata. However,
regardless of the situation, the code removed the inode from the
inode rbtree. That resulted in the dinode being considered unlinked,
so it would get improperly tossed into lost+found and left in a
indeterminate state. Subsequent runs of fsck.gfs2 could find the
discrepancy and flag it as unlinked again. This patch adds another
check so that the inode is not removed from the inode rbtree, so it
is linked properly during pass2.

rhbz#902920
---
 gfs2/fsck/pass1b.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index c9e6494..1cc2473 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -519,9 +519,12 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
 			  (unsigned long long)id->block_no);
 
 		ip = fsck_load_inode(sdp, id->block_no);
-		ii = inodetree_find(ip->i_di.di_num.no_addr);
-		if (ii)
-			inodetree_delete(ii);
+		if (id->reftypecount[ref_as_data] ||
+		    id->reftypecount[ref_as_meta]) {
+			ii = inodetree_find(ip->i_di.di_num.no_addr);
+			if (ii)
+				inodetree_delete(ii);
+		}
 		clear_dup_fxns.private = (void *) dh;
 		/* Clear the EAs for the inode first */
 		check_inode_eattr(ip, &clear_dup_fxns);


More information about the cluster-commits mailing list