gfs2-utils: master - fsck.gfs2: Add check for gfs1 invalid inode refs in dentry

Bob Peterson rpeterso at fedoraproject.org
Tue Sep 29 18:37:51 UTC 2015


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=ec1544385e555a8c890ee4ff4fafc948bc258bc5
Commit:        ec1544385e555a8c890ee4ff4fafc948bc258bc5
Parent:        ff58f4d283573bd7e2f1b6c5e42a35290aac5b66
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Mon Sep 14 16:23:49 2015 -0500
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Tue Sep 29 13:22:56 2015 -0500

fsck.gfs2: Add check for gfs1 invalid inode refs in dentry

This patch adds a check to function basic_dentry_checks for a
special case where a GFS1 dirent points to a non-inode. Since
GFS1 marked all its metadata as "metadata" (not just dinodes as
GFS2 does), we need to verify that GFS1 dirents actually point
to GFS1 dinodes. If they point to a different kind of metadata
block, we need to treat it as an error.
---
 gfs2/fsck/pass2.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 900d4e1..11777eb 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -611,6 +611,27 @@ static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			 (unsigned long long)ii->di_num.no_formal_ino);
 		return 1;
 	}
+	/* Check for a special case where a (bad) GFS1 dirent points to what
+	 * is not a known inode. It could be other GFS1 metadata, such as an
+	 * eattr or indirect block, but marked "dinode" in the bitmap because
+	 * gfs1 marked all gfs1 metadata that way. */
+	if (ii == NULL && sdp->gfs1) {
+		struct gfs2_buffer_head *tbh;
+
+		tbh = bread(sdp, entry->no_addr);
+		if (gfs2_check_meta(tbh, GFS2_METATYPE_DI)) { /* not dinode */
+			log_err( _("Directory entry '%s' pointing to block "
+				   "%llu (0x%llx) in directory %llu (0x%llx) "
+				   "is not really a GFS1 dinode.\n"), tmp_name,
+			 (unsigned long long)entry->no_addr,
+			 (unsigned long long)entry->no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr);
+			brelse(tbh);
+			return 1;
+		}
+		brelse(tbh);
+	}
 	return 0;
 }
 


More information about the cluster-commits mailing list