gfs2-utils: master - fsck.gfs2: If journal replay fails, give option to reinitialize journal

Bob Peterson rpeterso at fedoraproject.org
Tue Jan 26 21:11:23 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=af5fb68fd577aa089a343c75c46387b2b33abe6e
Commit:        af5fb68fd577aa089a343c75c46387b2b33abe6e
Parent:        ceef74fb4c29ffa8d8ec48a7d5122ca8f07d2a57
Author:        Bob Peterson <bob at ganesha.peterson>
AuthorDate:    Mon Jan 25 17:07:34 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Tue Jan 26 15:09:53 2010 -0600

fsck.gfs2: If journal replay fails, give option to reinitialize journal

When fsck.gfs2 finds a dirty journal, it tries (with permission) to
replay the journal.  However, if replaying the journal fails, the
user is left with no recourse.  Their file system is now useless.
This patch gives them the option to reinitialize the journal that
failed, thereby allowing them the ability to mount it again.

rhbz#455300
---
 gfs2/fsck/fs_recovery.c |   67 +++++++++++++++++++++++++---------------------
 1 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 5b9c1b1..89e43be 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -506,42 +506,47 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
 		error = FSCK_ERROR;
 		goto out;
 	}
-	if (query( _("\nJournal #%d (\"journal%d\") is dirty.  Okay to "
-		     "replay it? (y/n)"), j+1, j)) {
-		log_info( _("jid=%u: Replaying journal...\n"), j);
-
-		sd_found_jblocks = sd_replayed_jblocks = 0;
-		sd_found_metablocks = sd_replayed_metablocks = 0;
-		sd_found_revokes = 0;
-		sd_replay_tail = head.lh_tail;
-		for (pass = 0; pass < 2; pass++) {
-			error = foreach_descriptor(ip, head.lh_tail,
-						   head.lh_blkno, pass);
-			if (error)
-				goto out;
-		}
-		log_info( _("jid=%u: Found %u revoke tags\n"), j,
-			 sd_found_revokes);
-		gfs2_revoke_clean(sdp);
-		error = clean_journal(ip, &head);
+	if (!query( _("\nJournal #%d (\"journal%d\") is dirty.  Okay to "
+		      "replay it? (y/n)"), j+1, j))
+		goto reinit;
+
+	log_info( _("jid=%u: Replaying journal...\n"), j);
+
+	sd_found_jblocks = sd_replayed_jblocks = 0;
+	sd_found_metablocks = sd_replayed_metablocks = 0;
+	sd_found_revokes = 0;
+	sd_replay_tail = head.lh_tail;
+	for (pass = 0; pass < 2; pass++) {
+		error = foreach_descriptor(ip, head.lh_tail,
+					   head.lh_blkno, pass);
 		if (error)
 			goto out;
-		log_err( _("jid=%u: Replayed %u of %u journaled data blocks\n"),
-			j, sd_replayed_jblocks, sd_found_jblocks);
-		log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"),
-			j, sd_replayed_metablocks, sd_found_metablocks);
-	} else {
-		if (query( _("Do you want to clear the dirty journal instead? (y/n)"))) {
-			write_journal(sdp, sdp->md.journal[j], j,
-				      sdp->md.journal[j]->i_di.di_size /
-				      sdp->sd_sb.sb_bsize);
-			
-		} else
-			log_err( _("jid=%u: Dirty journal not replayed or cleared.\n"), j);
 	}
+	log_info( _("jid=%u: Found %u revoke tags\n"), j, sd_found_revokes);
+	gfs2_revoke_clean(sdp);
+	error = clean_journal(ip, &head);
+	if (error)
+		goto out;
+	log_err( _("jid=%u: Replayed %u of %u journaled data blocks\n"),
+		 j, sd_replayed_jblocks, sd_found_jblocks);
+	log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"),
+		 j, sd_replayed_metablocks, sd_found_metablocks);
 
+	/* Check for errors and give them the option to reinitialize the
+	   journal. */
 out:
-	log_info( _("jid=%u: %s\n"), j, (error) ? _("Failed") : _("Done"));
+	if (!error) {
+		log_info( _("jid=%u: Done\n"), j);
+		return 0;
+	}
+	log_info( _("jid=%u: Failed\n"), j);
+reinit:
+	if (query( _("Do you want to clear the journal instead? (y/n)")))
+		error = write_journal(sdp, sdp->md.journal[j], j,
+				      sdp->md.journal[j]->i_di.di_size /
+				      sdp->sd_sb.sb_bsize);
+	else
+		log_err( _("jid=%u: journal not cleared.\n"), j);
 	return error;
 }
 


More information about the cluster-commits mailing list