gfs2-utils: master - fsck.gfs2: make query() count errors_found, errors_fixed

Bob Peterson rpeterso at fedoraproject.org
Tue Jan 26 21:08:42 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=5635d4d90d0cfe5ebe66684431e20bf61325c3a1
Commit:        5635d4d90d0cfe5ebe66684431e20bf61325c3a1
Parent:        28f8b8791be9330a5d31aad46cefa886670e9162
Author:        Bob Peterson <bob at ganesha.peterson>
AuthorDate:    Wed Dec 2 14:42:55 2009 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Tue Jan 26 15:09:41 2010 -0600

fsck.gfs2: make query() count errors_found, errors_fixed

This patch changes the query() function so that it keeps track
of errors_found and errors_corrected.  This enforces a consistent
count of errors found and corrected so that the return code from
fsck.gfs2 is correct and future code changes that require calls
to query don't have to code it.  It also makes the calls a tiny
bit faster because they no longer have to pass the opt variable.

rhbz#455300
---
 gfs2/fsck/fs_recovery.c |   12 +++---
 gfs2/fsck/fsck.h        |    4 ++-
 gfs2/fsck/main.c        |    5 +--
 gfs2/fsck/metawalk.c    |   34 +++++--------------
 gfs2/fsck/pass1.c       |   34 +++++--------------
 gfs2/fsck/pass1b.c      |   19 ++++-------
 gfs2/fsck/pass1c.c      |    9 +----
 gfs2/fsck/pass2.c       |   80 +++++++++++++---------------------------------
 gfs2/fsck/pass3.c       |   23 +++++---------
 gfs2/fsck/pass4.c       |   24 +++++---------
 gfs2/fsck/pass5.c       |   22 +++++--------
 gfs2/fsck/rgrepair.c    |    9 +----
 gfs2/fsck/util.c        |   61 +++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/gfs2_log.c |    2 +-
 gfs2/libgfs2/libgfs2.h  |    1 +
 15 files changed, 149 insertions(+), 190 deletions(-)

diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 59a8443..acc83c9 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -449,9 +449,9 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
 				 "without -a or -p.\n"));
 			goto out;
 		}
-		if (!query(&opts, _("\nJournal #%d (\"journal%d\") is "
-				    "corrupt.  Okay to repair it? (y/n)"),
-			   j+1, j)) {
+		if (!query( _("\nJournal #%d (\"journal%d\") is "
+			      "corrupt.  Okay to repair it? (y/n)"),
+			    j+1, j)) {
 			log_err( _("jid=%u: The journal was not repaired.\n"),
 				 j);
 			goto out;
@@ -494,8 +494,8 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
 		error = FSCK_ERROR;
 		goto out;
 	}
-	if (query(&opts, _("\nJournal #%d (\"journal%d\") is dirty.  Okay to "
-			   "replay it? (y/n)"), j+1, j)) {
+	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;
@@ -519,7 +519,7 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
 		log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"),
 			j, sd_replayed_metablocks, sd_found_metablocks);
 	} else {
-		if (query(&opts, _("Do you want to clear the dirty journal instead? (y/n)"))) {
+		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);
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 840a526..bf3b74c 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -7,7 +7,7 @@
 #define FSCK_HASH_SIZE          (1 << FSCK_HASH_SHIFT)
 #define FSCK_HASH_MASK          (FSCK_HASH_SIZE - 1)
 
-#define query(opts, fmt, args...) gfs2_query(&fsck_abort, opts, fmt, ##args)
+#define query(fmt, args...) fsck_query(fmt, ##args)
 
 /*
  * Exit codes used by fsck-type programs
@@ -75,6 +75,8 @@ int pass3(struct gfs2_sbd *sbp);
 int pass4(struct gfs2_sbd *sbp);
 int pass5(struct gfs2_sbd *sbp);
 int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count);
+int fsck_query(const char *format, ...)
+	__attribute__((format(printf,1,2)));
 
 /* FIXME: Hack to get this going for pass2 - this should be pulled out
  * of pass1 and put somewhere else... */
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index df1b7f5..0bb3617 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -191,10 +191,7 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
 	 * system inodes before we can do any of that. */
 	if(!sysinode || ds.q.block_type != mark) {
 		log_err( _("Invalid or missing %s system inode.\n"), filename);
-		errors_found++;
-		if (query(&opts, _("Create new %s system inode? (y/n) "),
-			  filename)) {
-			errors_corrected++;
+		if (query(_("Create new %s system inode? (y/n) "), filename)) {
 			builder(sysinode->i_sbd);
 			gfs2_block_set(sysinode->i_sbd, bl,
 				       sysinode->i_di.di_num.no_addr,
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index c05cfe2..bcd8ab1 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -231,8 +231,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 				(*count) + 1,
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			errors_found++;
-			if (query(&opts, _("Attempt to repair it? (y/n) "))) {
+			if (query( _("Attempt to repair it? (y/n) "))) {
 				if (dirent_repair(ip, bh, &de, dent, type,
 						  first)) {
 					if (first) /* make a new sentinel */
@@ -247,7 +246,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 				} else {
 					log_err( _("Corrupt directory entry "
 						   "repaired.\n"));
-					errors_corrected++;
 					bmodified(bh);
 					/* keep looping through dentries */
 				}
@@ -271,8 +269,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 					(unsigned long long)bh->b_blocknr,
 					(unsigned long long)ip->i_di.di_num.no_addr,
 					(unsigned long long)ip->i_di.di_num.no_addr);
-				if (query(&opts,
-					  _("Attempt to remove it? (y/n) "))) {
+				if (query(_("Attempt to remove it? (y/n) "))) {
 					dirblk_truncate(ip, prev, bh);
 					log_err(_("The corrupt directory "
 						  "entry was removed.\n"));
@@ -338,10 +335,8 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
 			(unsigned long long)*leaf_no,
 			(unsigned long long)*leaf_no, msg);
 	}
-	errors_found++;
 	if (*leaf_no == *bad_leaf ||
-	    query(&opts, _("Attempt to patch around it? (y/n) "))) {
-		errors_corrected++;
+	    query( _("Attempt to patch around it? (y/n) "))) {
 		if (gfs2_check_range(ip->i_sbd, old_leaf) == 0)
 			gfs2_put_leaf_nr(ip, pindex, old_leaf);
 		else
@@ -419,11 +414,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 				 (unsigned long long)old_leaf,
 				 (unsigned long long)old_leaf,
 				 ref_count, exp_count);
-			errors_found++;
-			if (query(&opts, _("Attempt to fix it? (y/n) "))) {
+			if (query( _("Attempt to fix it? (y/n) "))) {
 				int factor = 0, divisor = ref_count;
 
-				errors_corrected++;
 				lbh = bread(&sbp->buf_list, old_leaf);
 				while (divisor > 1) {
 					factor++;
@@ -544,9 +537,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 						(unsigned long long)
 						ip->i_di.di_num.no_addr,
 						leaf.lf_entries, count);
-					errors_found++;
-					if(query(&opts, _("Update leaf entry count? (y/n) "))) {
-						errors_corrected++;
+					if(query( _("Update leaf entry count? (y/n) "))) {
 						leaf.lf_entries = count;
 						gfs2_leaf_out(&leaf, lbh->b_data);
 						log_warn( _("Leaf entry count updated\n"));
@@ -622,11 +613,8 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 							      bh, ea_hdr,
 							      ea_hdr_prev,
 							      pass->private)) {
-					errors_found++;
-					if (query(&opts, _("Repair the bad "
-							 "Extended Attribute? "
-							   "(y/n) "))) {
-						errors_corrected++;
+					if (query( _("Repair the bad Extended "
+						     "Attribute? (y/n) "))) {
 						ea_hdr->ea_num_ptrs = i;
 						ea_hdr->ea_data_len =
 							cpu_to_be32(tot_ealen);
@@ -742,13 +730,9 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
 			error = check_leaf_eattr(ip, block, indirect, pass);
 			if (error) {
 				leaf_pointer_errors++;
-				errors_found++;
-				if (query(&opts, _("Fix the indirect "
-						   "block too? (y/n) "))) {
-					bmodified(indirect_buf);
-					errors_corrected++;
+				if (query( _("Fix the indirect "
+					     "block too? (y/n) ")))
 					*ea_leaf_ptr = 0;
-				}
 			}
 			/* If the first eattr lead is bad, we can't have
 			   a hole, so we have to treat this as an unrecoverable
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 267028e..20c1cb8 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -207,12 +207,10 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 		const char *allocdesc[] = {"free space", "data", "unlinked",
 					   "metadata", "reserved"};
 
-		errors_found++;
 		log_err( _("Block %llu (0x%llx) seems to be data, but is "
 			   "marked as %s.\n"), (unsigned long long)block,
 			   (unsigned long long)block, allocdesc[btype]);
-		if(query(&opts, _("Okay to mark it as 'data'? (y/n)"))) {
-			errors_corrected++;
+		if(query( _("Okay to mark it as 'data'? (y/n)"))) {
 			gfs2_set_bitmap(ip->i_sbd, block, GFS2_BLKST_USED);
 			log_err( _("The block was reassigned as data.\n"));
 		} else {
@@ -246,12 +244,10 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip,
 	log_err( _("Inode %lld (0x%llx) has unrecoverable Extended Attribute "
 		   "errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr,
 		 (unsigned long long)ip->i_di.di_num.no_addr);
-	errors_found++;
-	if (query(&opts, _("Clear all Extended Attributes from the "
-			   "inode? (y/n) "))) {
+	if (query( _("Clear all Extended Attributes from the "
+		     "inode? (y/n) "))) {
 		struct gfs2_block_query q;
 
-		errors_corrected++;
 		if(gfs2_block_check(ip->i_sbd, bl, ip->i_di.di_eattr, &q)) {
 			stack;
 			return -1;
@@ -286,9 +282,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
 		(unsigned long long)ip->i_di.di_num.no_addr, emsg);
 	log_err( _(" at block #%lld (0x%llx).\n"),
 		 (unsigned long long)block, (unsigned long long)block);
-	errors_found++;
-	if (query(&opts, _("Clear the bad Extended Attribute? (y/n) "))) {
-		errors_corrected++;
+	if (query( _("Clear the bad Extended Attribute? (y/n) "))) {
 		if (block == ip->i_di.di_eattr) {
 			remove_inode_eattr(ip, bc, duplicate);
 			log_err( _("The bad extended attribute was "
@@ -393,10 +387,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
 		   "Extended Attribute errors.\n"),
 		   (unsigned long long)ip->i_di.di_num.no_addr,
 		   (unsigned long long)ip->i_di.di_num.no_addr);
-	errors_found++;
-	if (query(&opts, _("Okay to fix the block count for the inode? "
-			   "(y/n) "))) {
-		errors_corrected++;
+	if (query( _("Okay to fix the block count for the inode? (y/n) "))) {
 		ip->i_di.di_blocks = 1 + bc->indir_count +
 			bc->data_count + bc->ea_count;
 		bmodified(ip->i_bh);
@@ -685,11 +676,9 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
 			(unsigned long long)block,
 			(unsigned long long)ip->i_di.di_num.no_addr,
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		errors_found++;
-		if(query(&opts, _("Fix address in inode at block #%"
-				  PRIu64 " (0x%" PRIx64 ")? (y/n) "),
+		if(query( _("Fix address in inode at block #%"
+			    PRIu64 " (0x%" PRIx64 ")? (y/n) "),
 			 block, block)) {
-			errors_corrected++;
 			ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
 			gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
 			bmodified(ip->i_bh);
@@ -866,9 +855,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
 			  (unsigned long long)bc.indir_count,
 			  (unsigned long long)bc.data_count,
 			  (unsigned long long)bc.ea_count);
-		errors_found++;
-		if (query(&opts, _("Fix ondisk block count? (y/n) "))) {
-			errors_corrected++;
+		if (query( _("Fix ondisk block count? (y/n) "))) {
 			ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count +
 				bc.ea_count;
 			bmodified(ip->i_bh);
@@ -888,8 +875,6 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
 			  uint64_t block)
 {
 	if (gfs2_check_meta(bh, 0)) {
-		errors_found++;
-
 		log_info( _("Found invalid metadata at #%llu (0x%llx)\n"),
 			  (unsigned long long)block,
 			  (unsigned long long)block);
@@ -897,8 +882,7 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
 			stack;
 			return -1;
 		}
-		if(query(&opts, _("Okay to free the invalid block? (y/n)"))) {
-			errors_corrected++;
+		if(query( _("Okay to free the invalid block? (y/n)"))) {
 			gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
 			log_err( _("The invalid block was freed.\n"));
 		} else {
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 218878b..57b71e2 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -417,9 +417,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
 				  (unsigned long long)id->block_no,
 				  (unsigned long long)b->block_no,
 				  (unsigned long long)b->block_no);
-			errors_found++;
-			if (query(&opts, _("Clear the inode? (y/n) "))) {
-				errors_corrected++;
+			if (query( _("Clear the inode? (y/n) "))) {
 				log_warn( _("Clearing inode %lld (0x%llx)...\n"),
 					 (unsigned long long)id->block_no,
 					 (unsigned long long)id->block_no);
@@ -457,18 +455,15 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
 	}
 	osi_list_foreach(tmp, &b->ref_inode_list) {
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
-		errors_found++;
-		if (!(query(&opts, _("Okay to clear inode %lld (0x%llx)? "
-				     "(y/n) "),
-				     (unsigned long long)id->block_no,
-				     (unsigned long long)id->block_no))) {
+		if (!(query( _("Okay to clear inode %lld (0x%llx)? (y/n) "),
+			     (unsigned long long)id->block_no,
+			     (unsigned long long)id->block_no))) {
 			log_warn( _("The bad inode was not cleared...\n"));
 			continue;
 		}
-		errors_corrected++;
-		    log_warn( _("Clearing inode %lld (0x%llx)...\n"),
-			 (unsigned long long)id->block_no,
-			 (unsigned long long)id->block_no);
+		log_warn( _("Clearing inode %lld (0x%llx)...\n"),
+			  (unsigned long long)id->block_no,
+			  (unsigned long long)id->block_no);
 		ip = fsck_load_inode(sbp, id->block_no);
 		dh.b = b;
 		dh.id = id;
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index e9784c4..36c66e1 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -39,10 +39,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
 				  struct gfs2_ea_header *prev,
 				  int fix_curr, int fix_curr_len)
 {
-	errors_found++;
-	if (query(&opts, _("Remove the bad Extended Attribute entry? "
-			   "(y/n) "))) {
-		errors_corrected++;
+	if (query( _("Remove the bad Extended Attribute entry? (y/n) "))) {
 		if (fix_curr)
 			curr->ea_flags |= GFS2_EAFLAG_LAST;
 		if (fix_curr_len) {
@@ -63,9 +60,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
 
 static int ask_remove_eattr(struct gfs2_inode *ip)
 {
-	errors_found++;
-	if (query(&opts, _("Remove the bad Extended Attribute? (y/n) "))) {
-		errors_corrected++;
+	if (query( _("Remove the bad Extended Attribute? (y/n) "))) {
 		ip->i_di.di_eattr = 0;
 		bmodified(ip->i_bh);
 		log_err( _("Bad Extended Attribute removed.\n"));
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index e9c49c6..7ff55bc 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -202,10 +202,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			log_err( _("\tName length found  = %u\n"
 					"\tHash expected      = %u (0x%x)\n"),
 					de->de_name_len, calculated_hash, calculated_hash);
-			errors_found++;
-			if(query(&opts, _("Fix directory hash for %s? (y/n) "),
-					 filename)) {
-				errors_corrected++;
+			if(query( _("Fix directory hash for %s? (y/n) "),
+				  filename)) {
 				de->de_hash = calculated_hash;
 				gfs2_dirent_out(de, (char *)dent);
 				log_err( _("Directory entry hash for %s fixed.\n"), filename);
@@ -226,10 +224,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	if(gfs2_check_range(ip->i_sbd, entryblock)) {
 		log_err( _("Block # referenced by directory entry %s is out of range\n"),
 				tmp_name);
-		errors_found++;
-		if(query(&opts, 
-				 _("Clear directory entry tp out of range block? (y/n) "))) {
-			errors_corrected++;
+		if(query( _("Clear directory entry tp out of range block? (y/n) "))) {
 			log_err( _("Clearing %s\n"), tmp_name);
 			dirent2_del(ip, bh, prev_de, dent);
 			bmodified(bh);
@@ -252,9 +247,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		/* Handle bad blocks */
 		log_err( _("Found a bad directory entry: %s\n"), filename);
 
-		errors_found++;
-		if(query(&opts, _("Delete inode containing bad blocks? (y/n)"))) {
-			errors_corrected++;
+		if(query( _("Delete inode containing bad blocks? (y/n)"))) {
 			entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
 			check_inode_eattr(entry_ip, &pass2_fxns_delete);
 			check_metatree(entry_ip, &pass2_fxns_delete);
@@ -290,12 +283,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			 _("previously marked invalid") :
 			 _("is not an inode"));
 
-		errors_found++;
-		if(query(&opts, _("Clear directory entry to non-inode block? "
-				  "(y/n) "))) {
+		if(query( _("Clear directory entry to non-inode block? "
+			    "(y/n) "))) {
 			struct gfs2_buffer_head *bhi;
 
-			errors_corrected++;
 			dirent2_del(ip, bh, prev_de, dent);
 			bmodified(bh);
 			log_warn( _("Directory entry '%s' cleared\n"), tmp_name);
@@ -342,9 +333,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			 (unsigned long long)de->de_inum.no_addr,
 			 (unsigned long long)de->de_inum.no_addr,
 			 block_type_string(&q));
-		errors_found++;
-		if(query(&opts, _("Clear stale directory entry? (y/n) "))) {
-			errors_corrected++;
+		if(query( _("Clear stale directory entry? (y/n) "))) {
 			entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
 			check_inode_eattr(entry_ip, &clear_eattrs);
 			fsck_inode_put(entry_ip);
@@ -369,10 +358,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				" (0x%llx)\n"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			errors_found++;
-			if(query(&opts, _("Clear duplicate '.' entry? (y/n) "))) {
-
-				errors_corrected++;
+			if(query( _("Clear duplicate '.' entry? (y/n) "))) {
 				entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
 				check_inode_eattr(entry_ip, &clear_eattrs);
 				fsck_inode_put(entry_ip);
@@ -407,9 +393,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				(unsigned long long)de->de_inum.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			errors_found++;
-			if(query(&opts, _("Remove '.' reference? (y/n) "))) {
-				errors_corrected++;
+			if(query( _("Remove '.' reference? (y/n) "))) {
 				entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
 				check_inode_eattr(entry_ip, &clear_eattrs);
 				fsck_inode_put(entry_ip);
@@ -443,10 +427,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				"(0x%llx)\n"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			errors_found++;
-			if(query(&opts, _("Clear duplicate '..' entry? (y/n) "))) {
+			if(query( _("Clear duplicate '..' entry? (y/n) "))) {
 
-				errors_corrected++;
 				entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
 				check_inode_eattr(entry_ip, &clear_eattrs);
 				fsck_inode_put(entry_ip);
@@ -471,9 +453,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				"pointing to something that's not a directory"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			errors_found++;
-			if(query(&opts, _("Clear bad '..' directory entry? (y/n) "))) {
-				errors_corrected++;
+			if(query( _("Clear bad '..' directory entry? (y/n) "))) {
 				entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
 				check_inode_eattr(entry_ip, &clear_eattrs);
 				fsck_inode_put(entry_ip);
@@ -523,9 +503,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		log_err( _("%s: Hard link to block %" PRIu64" (0x%" PRIx64
 				") detected.\n"), filename, entryblock, entryblock);
 
-		errors_found++;
-		if(query(&opts, _("Clear hard link to directory? (y/n) "))) {
-			errors_corrected++;
+		if(query( _("Clear hard link to directory? (y/n) "))) {
 			bmodified(bh);
 			dirent2_del(ip, bh, prev_de, dent);
 			log_warn( _("Directory entry %s cleared\n"), filename);
@@ -605,9 +583,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 	}
 	if(!ds.dotdir) {
 		log_err( _("No '.' entry found for %s directory.\n"), dirname);
-		errors_found++;
-		if (query(&opts, _("Is it okay to add '.' entry? (y/n) "))) {
-			errors_corrected++;
+		if (query( _("Is it okay to add '.' entry? (y/n) "))) {
 			sprintf(tmp_name, ".");
 			filename_len = strlen(tmp_name); /* no trailing NULL */
 			if(!(filename = malloc(sizeof(char) * filename_len))) {
@@ -639,12 +615,10 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 			(unsigned long long)sysinode->i_di.di_num.no_addr,
 			(unsigned long long)sysinode->i_di.di_num.no_addr,
 			sysinode->i_di.di_entries, ds.entry_count);
-		errors_found++;
-		if(query(&opts, _("Fix entries for %s inode %llu (0x%llx"
-			 ")? (y/n) "), dirname,
-			 (unsigned long long)sysinode->i_di.di_num.no_addr,
-			 (unsigned long long)sysinode->i_di.di_num.no_addr)) {
-			errors_corrected++;
+		if(query( _("Fix entries for %s inode %llu (0x%llx)? (y/n) "),
+			  dirname,
+			  (unsigned long long)sysinode->i_di.di_num.no_addr,
+			  (unsigned long long)sysinode->i_di.di_num.no_addr)) {
 			sysinode->i_di.di_entries = ds.entry_count;
 			bmodified(sysinode->i_bh);
 			log_warn( _("Entries updated\n"));
@@ -768,12 +742,10 @@ int pass2(struct gfs2_sbd *sbp)
 			}
 			if(error == 0) {
 				/* FIXME: factor */
-				errors_found++;
-				if(query(&opts, _("Remove directory entry for bad"
-						 " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
-						 " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent,
-						 di->treewalk_parent)) {
-					errors_corrected++;
+				if(query( _("Remove directory entry for bad"
+					    " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
+					    " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent,
+					  di->treewalk_parent)) {
 					error = remove_dentry_from_dir(sbp, di->treewalk_parent,
 												   i);
 					if(error < 0) {
@@ -798,10 +770,7 @@ int pass2(struct gfs2_sbd *sbp)
 			log_err(_("No '.' entry found for directory inode at "
 				  "block %"PRIu64" (0x%" PRIx64 ")\n"), i, i);
 
-			errors_found++;
-			if (query(&opts,
-				  _("Is it okay to add '.' entry? (y/n) "))) {
-				errors_corrected++;
+			if (query( _("Is it okay to add '.' entry? (y/n) "))) {
 				sprintf(tmp_name, ".");
 				filename_len = strlen(tmp_name); /* no trailing
 								    NULL */
@@ -838,10 +807,7 @@ int pass2(struct gfs2_sbd *sbp)
 				ip->i_di.di_entries, ds.entry_count,
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			errors_found++;
-			if (query(&opts,
-				  _("Fix the entry count? (y/n) "))) {
-				errors_corrected++;
+			if (query( _("Fix the entry count? (y/n) "))) {
 				ip->i_di.di_entries = ds.entry_count;
 				bmodified(ip->i_bh);
 			} else {
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 09da4c6..88867be 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -120,12 +120,10 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
 
 				/* FIXME: add a dinode for this entry instead? */
 
-				errors_found++;
-				if(query(&opts, _("Remove directory entry for bad"
-						 " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
-						 " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode,
-						 di->treewalk_parent, di->treewalk_parent)) {
-					errors_corrected++;
+				if(query( _("Remove directory entry for bad"
+					    " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
+					    " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode,
+					  di->treewalk_parent, di->treewalk_parent)) {
 					error = remove_dentry_from_dir(sbp, di->treewalk_parent,
 												   di->dinode);
 					if(error < 0) {
@@ -223,10 +221,8 @@ int pass3(struct gfs2_sbd *sbp)
 				}
 				if(q.block_type == gfs2_bad_block) {
 					log_err( _("Found unlinked directory containing bad block\n"));
-					errors_found++;
-					if(query(&opts,
+					if(query(
 					   _("Clear unlinked directory with bad blocks? (y/n) "))) {
-						errors_corrected++;
 						gfs2_block_set(sbp, bl,
 							       di->dinode,
 							       gfs2_block_free);
@@ -255,9 +251,7 @@ int pass3(struct gfs2_sbd *sbp)
 				 * with eattrs */
 				if(!ip->i_di.di_size && !ip->i_di.di_eattr){
 					log_err( _("Unlinked directory has zero size.\n"));
-					errors_found++;
-					if(query(&opts, _("Remove zero-size unlinked directory? (y/n) "))) {
-						errors_corrected++;
+					if(query( _("Remove zero-size unlinked directory? (y/n) "))) {
 						gfs2_block_set(sbp, bl,
 							       di->dinode,
 							       gfs2_block_free);
@@ -267,9 +261,8 @@ int pass3(struct gfs2_sbd *sbp)
 						log_err( _("Zero-size unlinked directory remains\n"));
 					}
 				}
-				errors_found++;
-				if(query(&opts, _("Add unlinked directory to lost+found? (y/n) "))) {
-					errors_corrected++;
+				if(query( _("Add unlinked directory to "
+					    "lost+found? (y/n) "))) {
 					if(add_inode_to_lf(ip)) {
 						fsck_inode_put(ip);
 						stack;
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 0ebb5ce..0391ab3 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -70,10 +70,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
 					"bad blocks\n"),
 					(unsigned long long)ii->inode,
 					(unsigned long long)ii->inode);
-				errors_found++;
-				if(query(&opts,
-						 _("Delete unlinked inode with bad blocks? (y/n) "))) {
-					errors_corrected++;
+				if(query(  _("Delete unlinked inode with bad "
+					     "blocks? (y/n) "))) {
 					ip = fsck_load_inode(sbp, ii->inode);
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
@@ -97,8 +95,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
 					   "not an inode (%d)\n"),
 					 q.block_type);
 				ip = fsck_load_inode(sbp, ii->inode);
-				if(query(&opts, _("Delete unlinked inode "
-						  "? (y/n) "))) {
+				if(query(_("Delete unlinked inode? (y/n) "))) {
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
 					check_metatree(ip, &pass4_fxns_delete);
@@ -120,9 +117,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
 			 * them. */
 			if(!ip->i_di.di_size && !ip->i_di.di_eattr){
 				log_err( _("Unlinked inode has zero size\n"));
-				errors_found++;
-				if(query(&opts, _("Clear zero-size unlinked inode? (y/n) "))) {
-					errors_corrected++;
+				if(query( _("Clear zero-size unlinked inode? (y/n) "))) {
 					gfs2_block_set(sbp, bl, ii->inode,
 						       gfs2_block_free);
 					fsck_inode_put(ip);
@@ -130,9 +125,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
 				}
 
 			}
-			errors_found++;
-			if(query(&opts, _("Add unlinked inode to lost+found? (y/n)"))) {
-				errors_corrected++;
+			if(query( _("Add unlinked inode to lost+found? (y/n)"))) {
 				bmodified(ip->i_bh);
 				if(add_inode_to_lf(ip)) {
 					stack;
@@ -153,10 +146,9 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
 					ii->inode, ii->link_count, ii->counted_links);
 			/* Read in the inode, adjust the link count,
 			 * and write it back out */
-			errors_found++;
-			if(query(&opts, _("Update link count for inode %"
-				 PRIu64 " (0x%" PRIx64 ") ? (y/n) "), ii->inode, ii->inode)) {
-				errors_corrected++;
+			if(query( _("Update link count for inode %" PRIu64
+				    " (0x%" PRIx64 ") ? (y/n) "),
+				  ii->inode, ii->inode)) {
 				ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */
 				fix_inode_count(sbp, ii, ip);
 				bmodified(ip->i_bh);
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 6d2fc33..29a2d13 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -83,15 +83,14 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 		   So we ignore it. */
 		if (rg_status == GFS2_BLKST_UNLINKED &&
 		    block_status == GFS2_BLKST_FREE) {
-			errors_found++;
 			if (free_unlinked == -1) {
 				log_err( _("Unlinked inode block found at "
 					   "block %llu (0x%llx).\n"),
 					 (unsigned long long)block,
 					 (unsigned long long)block);
-				if(query(&opts, _("Do you want me to fix the "
-						  "bitmap for all unlinked "
-						  "blocks? (y/n) ")))
+				if(query( _("Do you want me to fix the "
+					    "bitmap for all unlinked "
+					    "blocks? (y/n) ")))
 					free_unlinked = 1;
 				else
 					free_unlinked = 0;
@@ -103,13 +102,11 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 						  "\n"),
 						(unsigned long long)block,
 						(unsigned long long)block);
-				else {
+				else
 					log_err(_("Unlinked block %llu "
 						  "(0x%llx) bitmap fixed.\n"),
 						(unsigned long long)block,
 						(unsigned long long)block);
-					errors_corrected++;
-				}
 			} else {
 				log_info( _("Unlinked block found at block %"
 					    PRIu64" (0x%" PRIx64 "), left "
@@ -127,10 +124,9 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 			log_err( _("Metadata type is %u (%s)\n"), q.block_type,
 					block_type_string(&q));
 
-			errors_found++;
-			if(query(&opts, _("Fix bitmap for block %"
-					 PRIu64" (0x%" PRIx64 ") ? (y/n) "), block, block)) {
-				errors_corrected++;
+			if(query( _("Fix bitmap for block %" PRIu64
+				    " (0x%" PRIx64 ") ? (y/n) "),
+				  block, block)) {
 				if(gfs2_set_bitmap(sbp, block, block_status))
 					log_err( _("Failed.\n"));
 				else
@@ -193,9 +189,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
 		exit(FSCK_ERROR);
 	}
 	if(update) {
-		errors_found++;
-		if(query(&opts, _("Update resource group counts? (y/n) "))) {
-			errors_corrected++;
+		if(query( _("Update resource group counts? (y/n) "))) {
 			log_warn( _("Resource group counts updated\n"));
 			/* write out the rgrp */
 			gfs2_rgrp_out(rg, rgbh[0]->b_data);
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index e835b84..8efe702 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -385,10 +385,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 		" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
 		rgbh[x]->b_blocknr, rgbh[x]->b_blocknr,
 		(int)x+1, (int)rgd->ri.ri_length);
-	errors_found++;
-	if (query(&opts, "Fix the RG? (y/n)")) {
-
-		errors_corrected++;
+	if (query( _("Fix the RG? (y/n)"))) {
 		log_err( _("Attempting to repair the RG.\n"));
 		rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
 		if (x) {
@@ -520,9 +517,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 		ri_compare(rg, actual->ri, expected->ri, ri_bitbytes, PRIx32);
 		/* If we modified the index, write it back to disk. */
 		if (rindex_modified) {
-			errors_found++;
-			if (query(&opts, _("Fix the index? (y/n)"))) {
-				errors_corrected++;
+			if (query( _("Fix the index? (y/n)"))) {
 				gfs2_rindex_out(&expected->ri, (char *)&buf);
 				gfs2_writei(sdp->md.riinode, (char *)&buf,
 					    rg * sizeof(struct gfs2_rindex),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 7e21b04..262bc6d 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -74,6 +74,7 @@ void warm_fuzzy_stuff(uint64_t block)
 			if (last_fs_block) {
 				percent = (block * 100) / last_fs_block;
 				log_notice( _("\r%" PRIu64 " percent complete.\r"), percent);
+				fflush(stdout);
 			}
 		}
 	}
@@ -90,3 +91,63 @@ const char *block_type_string(struct gfs2_block_query *q)
 		return (blktyp[q->block_type]);
 	return blktyp[15];
 }
+
+/* fsck_query: Same as gfs2_query except it adjusts errors_found and
+   errors_corrected. */
+int fsck_query(const char *format, ...)
+{
+	va_list args;
+	const char *transform;
+	char response;
+	int ret = 0;
+
+	errors_found++;
+	fsck_abort = 0;
+	if(opts.yes) {
+		errors_corrected++;
+		return 1;
+	}
+	if(opts.no)
+		return 0;
+
+	opts.query = TRUE;
+	while (1) {
+		va_start(args, format);
+		transform = _(format);
+		vprintf(transform, args);
+		va_end(args);
+
+		/* Make sure query is printed out */
+		fflush(NULL);
+		response = gfs2_getch();
+
+		printf("\n");
+		fflush(NULL);
+		if (response == 0x3) { /* if interrupted, by ctrl-c */
+			response = generic_interrupt("Question", "response",
+						     NULL,
+						     "Do you want to abort " \
+						     "or continue (a/c)?",
+						     "ac");
+			if (response == 'a') {
+				ret = 0;
+				fsck_abort = 1;
+				break;
+			}
+			printf("Continuing.\n");
+		} else if(tolower(response) == 'y') {
+			errors_corrected++;
+                        ret = 1;
+                        break;
+ 		} else if (tolower(response) == 'n') {
+			ret = 0;
+			break;
+		} else {
+			printf("Bad response %d, please type 'y' or 'n'.\n",
+			       response);
+		}
+	}
+
+	opts.query = FALSE;
+	return ret;
+}
diff --git a/gfs2/libgfs2/gfs2_log.c b/gfs2/libgfs2/gfs2_log.c
index 86d2089..d2d3379 100644
--- a/gfs2/libgfs2/gfs2_log.c
+++ b/gfs2/libgfs2/gfs2_log.c
@@ -74,7 +74,7 @@ void print_fsck_log(int iif, int priority, const char *file, int line,
 	va_end(args);
 }
 
-static char gfs2_getch(void)
+char gfs2_getch(void)
 {
 	struct termios termattr, savetermattr;
 	char ch;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 0428481..1f10027 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -586,6 +586,7 @@ do { print_log(1, MSG_ERROR, format); } while(0)
 #define log_at_crit(format...) \
 do { print_log(1, MSG_CRITICAL, format); } while(0)
 
+extern char gfs2_getch(void);
 extern void increase_verbosity(void);
 extern void decrease_verbosity(void);
 extern void print_fsck_log(int iif, int priority, const char *file, int line,


More information about the cluster-commits mailing list