gfs2-utils: RHEL7 - fsck.gfs2: Rebuild system files if they don't have the SYS bit set

Andrew Price andyp at fedoraproject.org
Tue Apr 7 21:23:44 UTC 2015


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=33aba2e2eac3c7b920230eff868d14a1d48c1f8f
Commit:        33aba2e2eac3c7b920230eff868d14a1d48c1f8f
Parent:        1ecf5d89fa0ea0d707531e8e77305b4dc0bdc32b
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Fri Jan 9 12:27:57 2015 -0600
Committer:     Andrew Price <anprice at redhat.com>
CommitterDate: Wed Apr 1 16:51:35 2015 +0100

fsck.gfs2: Rebuild system files if they don't have the SYS bit set

This patch checks for the GFS2_DIF_SYSTEM bit on system dinodes. If the
bit is not set, the dinode is assumed to be corrupt and rebuilt.
If the jindex is rebuilt, it needs to be re-read.
---
 gfs2/fsck/pass1.c |   55 +++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 2841b8c..4348683 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -27,6 +27,7 @@
 #include "util.h"
 #include "link.h"
 #include "metawalk.h"
+#include "fs_recovery.h"
 
 struct special_blocks gfs1_rindex_blks;
 
@@ -1241,7 +1242,8 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 			      struct gfs2_inode **sysinode,
 			      const char *filename,
 			      int builder(struct gfs2_sbd *sdp),
-			      enum gfs2_mark_block mark)
+			      enum gfs2_mark_block mark,
+			      struct gfs2_inode *sysdir, int needs_sysbit)
 {
 	uint64_t iblock = 0;
 	struct dir_status ds = {0};
@@ -1282,6 +1284,24 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 			if (mark == gfs2_inode_dir)
 				dirtree_insert((*sysinode)->i_di.di_num);
 		}
+		/* Make sure it's marked as a system file/directory */
+		if (needs_sysbit &&
+		    !((*sysinode)->i_di.di_flags & GFS2_DIF_SYSTEM)) {
+			log_err( _("System inode %s is missing the 'system' "
+				   "flag. It should be rebuilt.\n"), filename);
+			if (sysdir && query(_("Delete the corrupt %s system "
+					      "inode? (y/n) "), filename)) {
+				inode_put(sysinode);
+				gfs2_dirent_del(sysdir, filename,
+						strlen(filename));
+				/* Set the blockmap (but not bitmap) back to
+				   'free' so that it gets checked like any
+				   normal dinode. */
+				gfs2_blockmap_set(bl, iblock, gfs2_block_free);
+				log_err( _("Removed system inode \"%s\".\n"),
+					 filename);
+			}
+		}
 	} else
 		log_info( _("System inode for '%s' is corrupt or missing.\n"),
 			  filename);
@@ -1290,18 +1310,22 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 	   lost+found then, but we *need* our system inodes before we can
 	   do any of that. */
 	if (!(*sysinode) || ds.q != mark) {
-		log_err( _("Invalid or missing %s system inode (should be %d, "
-			   "is %d).\n"), filename, mark, ds.q);
+		log_err( _("Invalid or missing %s system inode (should be "
+			   "'%s', is '%s').\n"), filename,
+			 block_type_string(mark),
+			 block_type_string(ds.q));
 		if (query(_("Create new %s system inode? (y/n) "), filename)) {
 			log_err( _("Rebuilding system file \"%s\"\n"),
 				 filename);
 			error = builder(sdp);
 			if (error) {
-				log_err( _("Error trying to rebuild system "
-					   "file %s: Cannot continue\n"),
+				log_err( _("Error rebuilding system "
+					   "inode %s: Cannot continue\n"),
 					 filename);
 				return error;
 			}
+			if (*sysinode == sdp->md.jiinode)
+				ji_update(sdp);
 			fsck_blockmap_set(*sysinode,
 					  (*sysinode)->i_di.di_num.no_addr,
 					  filename, mark);
@@ -1367,7 +1391,8 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 				  sdp->master_dir->i_di.di_num.no_addr,
 				  "master", gfs2_inode_dir);
 		if (check_system_inode(sdp, &sdp->master_dir, "master",
-				       build_master, gfs2_inode_dir)) {
+				       build_master, gfs2_inode_dir,
+				       NULL, 1)) {
 			stack;
 			return -1;
 		}
@@ -1377,39 +1402,41 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 	fsck_blockmap_set(sdp->md.rooti, sdp->md.rooti->i_di.di_num.no_addr,
 			  "root", gfs2_inode_dir);
 	if (check_system_inode(sdp, &sdp->md.rooti, "root", build_root,
-			       gfs2_inode_dir)) {
+			       gfs2_inode_dir, NULL, 0)) {
 		stack;
 		return -1;
 	}
 	if (!sdp->gfs1 &&
 	    check_system_inode(sdp, &sdp->md.inum, "inum", build_inum,
-			       gfs2_inode_file)) {
+			       gfs2_inode_file, sdp->master_dir, 1)) {
 		stack;
 		return -1;
 	}
 	if (check_system_inode(sdp, &sdp->md.statfs, "statfs", build_statfs,
-			       gfs2_inode_file)) {
+			       gfs2_inode_file, sdp->master_dir, !sdp->gfs1)) {
 		stack;
 		return -1;
 	}
 	if (check_system_inode(sdp, &sdp->md.jiinode, "jindex", build_jindex,
-			       (sdp->gfs1 ? gfs2_inode_file : gfs2_inode_dir))) {
+			       (sdp->gfs1 ? gfs2_inode_file : gfs2_inode_dir),
+			       sdp->master_dir, !sdp->gfs1)) {
 		stack;
 		return -1;
 	}
 	if (check_system_inode(sdp, &sdp->md.riinode, "rindex", build_rindex,
-			       gfs2_inode_file)) {
+			       gfs2_inode_file, sdp->master_dir, !sdp->gfs1)) {
 		stack;
 		return -1;
 	}
 	if (check_system_inode(sdp, &sdp->md.qinode, "quota", build_quota,
-			       gfs2_inode_file)) {
+			       gfs2_inode_file, sdp->master_dir, !sdp->gfs1)) {
 		stack;
 		return -1;
 	}
 	if (!sdp->gfs1 &&
 	    check_system_inode(sdp, &sdp->md.pinode, "per_node",
-			       build_per_node, gfs2_inode_dir)) {
+			       build_per_node, gfs2_inode_dir,
+			       sdp->master_dir, 1)) {
 		stack;
 		return -1;
 	}
@@ -1438,7 +1465,7 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 		sprintf(jname, "journal%d", sdp->md.journals);
 		if (check_system_inode(sdp, &sdp->md.journal[sdp->md.journals],
 				       jname, build_a_journal,
-				       gfs2_inode_file)) {
+				       gfs2_inode_file, sdp->md.jiinode, 1)) {
 			stack;
 			return -1;
 		}


More information about the cluster-commits mailing list