[Ocfs2-tools-commits] zab commits r433 - in trunk: . fsck.ocfs2 fsck.ocfs2/include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Nov 22 18:17:59 CST 2004


Author: zab
Date: 2004-11-22 18:17:57 -0600 (Mon, 22 Nov 2004)
New Revision: 433

Added:
   trunk/fsck.ocfs2/fsck.ocfs2.8.in
   trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in
Modified:
   trunk/configure.in
   trunk/fsck.ocfs2/Makefile
   trunk/fsck.ocfs2/extent.c
   trunk/fsck.ocfs2/include/problem.h
   trunk/fsck.ocfs2/journal.c
   trunk/fsck.ocfs2/pass0.c
   trunk/fsck.ocfs2/pass1.c
   trunk/fsck.ocfs2/pass2.c
   trunk/fsck.ocfs2/pass3.c
   trunk/fsck.ocfs2/pass4.c
   trunk/fsck.ocfs2/problem.c
Log:
o get rid of the bad and unused fatal prompt flag
o add some fsck man pages
o introduce error codes to associate prompts and the man pages


Modified: trunk/configure.in
===================================================================
--- trunk/configure.in	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/configure.in	2004-11-23 00:17:57 UTC (rev 433)
@@ -194,6 +194,8 @@
 libocfs2/ocfs2_err.et
 debugfs.ocfs2/debugfs.ocfs2.8
 mkfs.ocfs2/mkfs.ocfs2.8
+fsck.ocfs2/fsck.ocfs2.8
+fsck.ocfs2/fsck.ocfs2.checks.8
 ocfs2tool/ocfs2tool.8
 ocfs_uid_gen/ocfs_uid_gen.8
 load_ocfs/load_ocfs.8

Modified: trunk/fsck.ocfs2/Makefile
===================================================================
--- trunk/fsck.ocfs2/Makefile	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/Makefile	2004-11-23 00:17:57 UTC (rev 433)
@@ -50,8 +50,9 @@
 		include/util.h
 
 OBJS = $(subst .c,.o,$(CFILES))
+MANS = fsck.ocfs2.8 fsck.ocfs2.checks.8
 
-DIST_FILES = $(CFILES) $(HFILES) 
+DIST_FILES = $(CFILES) $(HFILES) $(addsuffix .in,$(MANS))
 DIST_RULES = dist-subdircreate
 
 dist-subdircreate:

Modified: trunk/fsck.ocfs2/extent.c
===================================================================
--- trunk/fsck.ocfs2/extent.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/extent.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -92,7 +92,7 @@
 	eb = (ocfs2_extent_block *)buf;
 
 	if (eb->h_blkno != blkno &&
-	    prompt(ost, PY, "An extent block at %"PRIu64" in inode %"PRIu64" "
+	    prompt(ost, PY, 0, "An extent block at %"PRIu64" in inode %"PRIu64" "
 		   "claims to be located at block %"PRIu64".  Update the "
 		   "extent block's location?", blkno, di->i_blkno,
 		   eb->h_blkno)) {
@@ -101,7 +101,7 @@
 	}
 
 	if (eb->h_fs_generation != ost->ost_fs_generation) {
-		if (prompt(ost, PY, "An extent block at %"PRIu64" in inode "
+		if (prompt(ost, PY, 0, "An extent block at %"PRIu64" in inode "
 			   "%"PRIu64" has a generation of %x which doesn't "
 			   "match the volume's generation of %x.  Consider "
 			   "this extent block invalid?", blkno, di->i_blkno,
@@ -110,7 +110,7 @@
 			*is_valid = 0;
 			goto out;
 		}
-		if (prompt(ost, PY, "Update the extent block's generation to "
+		if (prompt(ost, PY, 0, "Update the extent block's generation to "
 			   "match the volume?")) {
 
 			eb->h_fs_generation = ost->ost_fs_generation;
@@ -166,7 +166,7 @@
 		ei->ei_expected_depth = el->l_tree_depth - 1;
 		check_eb(ost, ei, di, er->e_blkno, &is_valid);
 		if (!is_valid && 
-		    prompt(ost, PY, "The extent record for cluster offset "
+		    prompt(ost, PY, 0, "The extent record for cluster offset "
 			   "%"PRIu32" in inode %"PRIu64" refers to an invalid "
 			   "extent block at %"PRIu64".  Clear the reference "
 			   "to this invalid block?", er->e_cpos, di->i_blkno,
@@ -183,7 +183,7 @@
 	first_block = ocfs2_clusters_to_blocks(ost->ost_fs, first_block);
 
 	if (first_block != er->e_blkno &&
-	    prompt(ost, PY, "The extent record for cluster offset %"PRIu32" "
+	    prompt(ost, PY, 0, "The extent record for cluster offset %"PRIu32" "
 		   "in inode %"PRIu64" refers to block %"PRIu64" which isn't "
 		   "aligned with the start of a cluster.  Point the extent "
 		   "record at block %"PRIu64" which starts this cluster?",
@@ -199,7 +199,7 @@
 		       er->e_clusters;
 
 	if (last_cluster > ost->ost_fs->fs_clusters &&
-	    prompt(ost, PY, "The extent record for cluster offset %"PRIu32" "
+	    prompt(ost, PY, 0, "The extent record for cluster offset %"PRIu32" "
 		   "in inode %"PRIu64" refers to an extent that goes beyond "
 		   "the end of the volume.  Truncate the extent by %"PRIu32" "
 		   "clusters to fit it in the volume?", er->e_cpos, 
@@ -233,7 +233,7 @@
 
 	if (ei->ei_expect_depth && 
 	    el->l_tree_depth != ei->ei_expected_depth &&
-	    prompt(ost, PY, "Extent list in inode %"PRIu64" is recorded as "
+	    prompt(ost, PY, 0, "Extent list in inode %"PRIu64" is recorded as "
 		   "being at depth %u but we expect it to be at depth %u. "
 		   "update the list?", di->i_blkno, el->l_tree_depth,
 		   ei->ei_expected_depth)) {
@@ -243,7 +243,7 @@
 	}
 
 	if (el->l_count > max_recs &&
-	    prompt(ost, PY, "Extent list in inode %"PRIu64" claims to have %u "
+	    prompt(ost, PY, 0, "Extent list in inode %"PRIu64" claims to have %u "
 		   "records, but the maximum is %u. Fix the list's count?",
 		   di->i_blkno, el->l_count, max_recs)) {
 
@@ -255,7 +255,7 @@
 		max_recs = el->l_count;
 
 	if (el->l_next_free_rec > max_recs) {
-		if (prompt(ost, PY, "Extent list in inode %"PRIu64" claims %u "
+		if (prompt(ost, PY, 0, "Extent list in inode %"PRIu64" claims %u "
 			   "as the next free chain record, but fsck believes "
 			   "the largest valid value is %u.  Clamp the next "
 			   "record value?", di->i_blkno, el->l_next_free_rec,
@@ -281,7 +281,7 @@
 
 		/* offer to remove records that point to nowhere */
 		if (ocfs2_block_out_of_range(ost->ost_fs, er->e_blkno) && 
-		    prompt(ost, PY, "Extent record %u in inode %"PRIu64" "
+		    prompt(ost, PY, 0, "Extent record %u in inode %"PRIu64" "
 			   "refers to a block that is out of range.  Remove "
 			   "this record from the extent list?", i,
 			   di->i_blkno)) {

Added: trunk/fsck.ocfs2/fsck.ocfs2.8.in
===================================================================
--- trunk/fsck.ocfs2/fsck.ocfs2.8.in	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/fsck.ocfs2.8.in	2004-11-23 00:17:57 UTC (rev 433)
@@ -0,0 +1,83 @@
+.TH "fsck.ocfs2" "8" "November 2004" "Version @VERSION@" "OCFS2 Manual Pages"
+.SH "NAME"
+fsck.ocfs2 \- Check an OCFS2 file system.
+.SH "SYNOPSIS"
+\fBfsck.ocfs2\fR [ \fB\-npuvy\fR ] [ \fB\-b\fR \fIsuperblock block\fR ] [ \fB\-B\fR \fIblock size\fR ] \fIdevice\fR
+.SH "DESCRIPTION"
+.PP 
+\fBfsck.ocfs2\fR is used to check an OCFS2 file system.
+
+\fIdevice\fR is the file where the file system is stored (e.g. \fI/dev/sda1\fR).  It will almost always be a device file but a regular file will work as well.
+
+.SH "OPTIONS"
+.TP
+\fB\-b\fR \fIsuperblock block\fR
+Normally, \fBfsck.ocfs2\fR will read the superblock from the first block of
+the device.  This option specifies an alternate block that the superblock
+should be read from.
+
+.TP
+\fB\-b\fR \fIblock size\fR
+The \fIblock size\fR, specified in bytes, can range from 512 to 4096.  A value of 0, the default, is used to indicate that the blocksize should be automatically detected.
+
+.TP
+\fB\-f\fR
+Force checking even if the file system is clean.  This currently has no
+effect as the file system is always checked.
+
+.TP
+\fB\-n\fR
+Give the 'no' answer to all questions that fsck will ask.  This guarantees
+that the file system will not be modified and the device will be opened
+read-only.  The output of \fBfsck.ocfs2\fR with this option can be redirected
+to produce a record of a file system's faults.
+
+.TP
+\fB\-p\fR
+Automatically repair ("preen") the file system without asking any questions.  This is currently identical to giving the \fB\-y\fR option.
+
+.TP
+\fB\-y\fR 
+Give the 'yes' answer to all questions that fsck will ask.  This will repair
+all faults that \fBfsck.ocfs2\fR finds but will not give the operator a chance to intervene if \fBfsck.ocfs2\fR decides that it wants to drastically repair the file system.
+
+.TP
+\fB\-v\fR 
+This option causes \fBfsck.ocfs2\fR to produce a very large amount of debugging output.
+
+.TP
+\fB\-V\fR 
+Print version information and exit.
+
+.SH EXIT CODE
+The exit code returned by \fBfsck.ocfs2\fR is the sum of the following conditions:
+.br
+\	0\	\-\ No errors
+.br
+\	1\	\-\ File system errors corrected
+.br
+\	2\	\-\ File system errors corrected, system should
+.br
+\	\	\ \ be rebooted
+.br
+\	4\	\-\ File system errors left uncorrected
+.br
+\	8\	\-\ Operational error
+.br
+\	16\	\-\ Usage or syntax error
+.br
+\	32\	\-\ E2fsck canceled by user request
+.br
+\	128\	\-\ Shared library error
+.br
+
+.SH "SEE ALSO"
+.BR ocfs2(8)
+
+.SH "AUTHORS"
+Oracle Corporation.  This man page entry derives some text, especially the exit code summary, from
+.BR e2fsck(8)
+by Theodore Ts’o <tytso at mit.edu>. 
+
+.SH "COPYRIGHT"
+Copyright \(co 2004 Oracle Corporation

Added: trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in
===================================================================
--- trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in	2004-11-23 00:17:57 UTC (rev 433)
@@ -0,0 +1,118 @@
+.TH "fsck.ocfs2" "8" "November 2004" "Version @VERSION@" "OCFS2 Manual Pages"
+.SH "NAME"
+fsck.ocfs2.checks \- Consistency checks that 
+.BR fsck.ocfs2(8)
+performs and its means for fixing inconsistencies.
+.SH "DESCRIPTION"
+.PP 
+.BR fsck.ocfs2(8)
+is used to check an OCFS2 file system.  It performs many consistenty checks and will offer to fix faults that it finds.  This man page lists the problems it may find and describes their fixes.  The problems are indexed by the error number that 
+.BR fsck.ocfs2(8)
+emits when it describes the problem and asks if it should be fixed.
+
+The prompts are constructed such that answering 'no' results in no changes to the file system.  This may result in errors later on that stop 
+.BR fsck.ocfs2(8)
+from proceeding.
+
+.SH "CHECKS"
+
+.SS "1"
+Each node's journals are usually empty after an orderly shut down of the
+file system.  A node was marked as not having shut down properly so its
+journal should be replayed.
+
+Answering yes replays the given node's journal.  Each block in the journal will be written
+to its intended location in the file system. 
+
+.SS "2"
+The group descriptors that make up the global bitmap chain allocator are
+static and should be found in specific chains in the allocator.  A given
+group descriptor wasn't found in the chain it should have been in.
+
+Answering yes relinks the given group descriptor into the head of the chain it
+should have been found in.
+
+.SS "3"
+The group descriptors that make up the global bitmap chain allocator are
+static and should be found in specific chains in the allocator.  A given
+group descriptor block existed on disk but wasn't linked into the global
+bitmap chain allocator.
+
+Answering yes links the given group descriptor into the global bitmap chain
+allocator.
+
+.SS "4"
+The chain list embedded in an inode is limited by the block size and the
+number of bytes consumed by the rest of the inode.  A chain list header was
+found which claimed that there are more entries in the list then could 
+fit in the inode.
+
+Answering yes resets the header's cl_count member to the maximum size allowed
+by the block size after accounting for the space consumed by the inode.
+
+.SS "5"
+This is identical to test 4 except that it is testing and fixing the pointer
+to the next free list entry recorded in the cl_next_free_rec member instead of
+the total number of entries. 
+
+.SS "6"
+Chain entries need to be packed such that there are no chains without 
+descriptors found before the chain that is marked as free by the chain header.
+A chain without descriptors was found found before that chain that was
+marked free.
+
+Answering yes will remove the unused chain and shift the remaining chains
+forward in the list.
+
+.SS "7"
+The inode that contains an embedded chain list has fields which record the
+total number of bits covered by the chain as well as the amount free.  These 
+fields didn't match what was found in the chain. 
+
+Answering yes updates the fields in the inode to reflect what was actually
+found by walking the chain.
+
+.SS "8"
+Chains are built by the chain headers and group descriptors which are linked
+together by block references.  A reference a block reference was found which
+can't possibly be valid because it was either too small or extended beyond the
+volume.
+
+Answering yes truncates the chain in question by zeroing the invalid block
+reference.  This shortens the chain in question and could result in more
+fixes later if the part of the chain that couldn't be referenced was valid
+at some point.
+
+.SS "10"
+The global bitmap chain allocator contains fixed blocks at predictable 
+offsets in the volume.  A group descriptor was found in this chain which
+wasn't at one of these predictable locations.
+
+Answering yes removes this unexpected group descriptor from the chain.  It's
+block will likely then be unused and marked as free in the bitmap later on.
+
+.SS "11"
+A reference was made to a group descriptor that is invalid, for whatever
+reason.
+
+Answering yes truncates the chain in question by removing the reference to
+this invalid group descriptor.  This has the same implications as answering
+yes to check 8. 
+
+.SS "12"
+A chain's header contains members which record the total number of bits in the
+chain as well as the number of bits that are free.  After walking through a
+chain it was found that the number of bits recorded in its header don't match
+what was found by totalling up the group descriptors.
+
+Answering yes updates the c_total and c_free members of the header to reflect
+what was found in the group descriptors in the chain.
+
+.SH "SEE ALSO"
+.BR ocfs2(8)
+
+.SH "AUTHORS"
+Oracle Corporation.
+
+.SH "COPYRIGHT"
+Copyright \(co 2004 Oracle Corporation

Modified: trunk/fsck.ocfs2/include/problem.h
===================================================================
--- trunk/fsck.ocfs2/include/problem.h	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/include/problem.h	2004-11-23 00:17:57 UTC (rev 433)
@@ -27,15 +27,15 @@
 /* prompt flags. */
 #define PY (1 << 0) /* default to yes when asked and no answer forced */
 #define PN  (1 << 1) /* default to no when asked and no answer forced */
-#define PF  (1 << 2) /* exit with FSCK_ERROR if 'n' is given */
 
 #include "fsck.h"
 
 /* returns non-zero for yes and zero for no.  The caller is expected to
  * provide a thorough description of the state and the action that will
  * be taken depending on the answer.  Without \n termination. */
-int prompt(o2fsck_state *ost, unsigned flags, const char *fmt, ...)
-	 __attribute__ ((format (printf, 3, 4)));
+int prompt(o2fsck_state *ost, unsigned flags, unsigned code, 
+	   const char *fmt, ...)
+	 __attribute__ ((format (printf, 4, 5)));
 
 #endif /* __O2FSCK_PROBLEM_H__ */
 

Modified: trunk/fsck.ocfs2/journal.c
===================================================================
--- trunk/fsck.ocfs2/journal.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/journal.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -591,8 +591,8 @@
 		if (!ji->ji_replay)
 			continue;
 
-		if (!prompt(ost, PY, "Node %d's journal needs to be replayed. "
-			    "Do so?", i)) {
+		if (!prompt(ost, PY, 1, "Node %d's journal needs to be "
+			    "replayed. Do so?", i)) {
 			journal_trouble = 1;
 			continue;
 		}

Modified: trunk/fsck.ocfs2/pass0.c
===================================================================
--- trunk/fsck.ocfs2/pass0.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/pass0.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -90,7 +90,7 @@
 	}
 
 	if (bg->bg_generation != ost->ost_fs_generation) {
-		if (prompt(ost, PY, "Group descriptor at block %"PRIu64" has "
+		if (prompt(ost, PY, 0, "Group descriptor at block %"PRIu64" has "
 			   "a generation of %"PRIx32" which doesn't match the "
 			   "volume's generation of %"PRIx32".  Delete this "
 			   "group descriptor?", blkno, bg->bg_generation,
@@ -98,7 +98,7 @@
 
 			return 1;
 		}
-		if (prompt(ost, PY, "Update the descriptor's generation to "
+		if (prompt(ost, PY, 0, "Update the descriptor's generation to "
 			   "match the volume?")) {
 
 			bg->bg_generation = ost->ost_fs_generation;
@@ -110,7 +110,7 @@
 	 * kinds of descs have valid generations for the inodes they
 	 * reference */
 	if ((bg->bg_parent_dinode != di->i_blkno) &&
-	    prompt(ost, PY, "Group descriptor at block %"PRIu64" is "
+	    prompt(ost, PY, 0, "Group descriptor at block %"PRIu64" is "
 		   "referenced by inode %"PRIu64" but thinks its parent inode "
 		   "is %"PRIu64".  Fix the descriptor's parent inode?", blkno,
 		   di->i_blkno, bg->bg_parent_dinode)) {
@@ -119,7 +119,7 @@
 	}
 
 	if ((bg->bg_generation != di->i_generation) &&
-	    prompt(ost, PY, "Group descriptor at block %"PRIu64" is "
+	    prompt(ost, PY, 0, "Group descriptor at block %"PRIu64" is "
 		   "referenced by inode %"PRIu64" who has a generation of "
 		   "%u, but the descriptor has a generation of %u.  Update "
 		   "the descriptor's generation?", blkno, di->i_blkno,
@@ -129,7 +129,7 @@
 	}
 
 	if ((bg->bg_blkno != blkno) &&
-	    prompt(ost, PY, "Group descriptor read from block %"PRIu64" "
+	    prompt(ost, PY, 0, "Group descriptor read from block %"PRIu64" "
 		   "claims to be located at block %"PRIu64".  Update its "
 		   "recorded block location?", blkno, di->i_blkno)) {
 		bg->bg_blkno = blkno;
@@ -137,7 +137,7 @@
 	}
 
 	if ((bg->bg_chain != cs->cs_chain_no) &&
-	    prompt(ost, PY, "Group descriptor at block %"PRIu64" was "
+	    prompt(ost, PY, 0, "Group descriptor at block %"PRIu64" was "
 		   "found in chain %u but it claims to be in chain %u. Update "
 		   "the descriptor's recorded chain?", blkno, cs->cs_chain_no,
 		   bg->bg_chain)) {
@@ -146,7 +146,7 @@
 	}
 
 	if ((bg->bg_free_bits_count > bg->bg_bits) &&
-	    prompt(ost, PY, "Group descriptor at block %"PRIu64" claims to "
+	    prompt(ost, PY, 0, "Group descriptor at block %"PRIu64" claims to "
 		   "have %u free bits which is more than its %u total bits. "
 		   "Drop its free bit count down to the total?", blkno,
 		   bg->bg_free_bits_count, bg->bg_bits)) {
@@ -192,11 +192,12 @@
 	memset(cbr, 0, sizeof(*cbr));
 
 	if (ocfs2_block_out_of_range(ost->ost_fs, blkno)) {
-		if (prompt(ost, PY, "Chain %d in allocator at inode %"PRIu64" "
-			   "points to block %"PRIu64" which is out of range. "
-			   "Truncate this chain by deleting this invalid "
-			   "block reference?", cs->cs_chain_no, di->i_blkno,
-			   blkno))  {
+		if (prompt(ost, PY, 8, "Chain %d in allocator at inode "
+			   "%"PRIu64" points to block %"PRIu64" which is out "
+			   "of range. Truncate this chain by deleting this "
+			   "invalid block reference?", cs->cs_chain_no,
+			   di->i_blkno, blkno))  {
+
 			cbr->cb_new_next_blkno = 1;
 			cbr->cb_next_blkno = 0;
 		} else {
@@ -208,7 +209,7 @@
 
 #if 0 /* XXX plausible + used test */
 	if (o2fsck_test_block_used(ost, blkno) &&
-	    prompt(ost, PY, "Chain %d in allocator at inode %"PRIu64" "
+	    prompt(ost, PY, 9, "Chain %d in allocator at inode %"PRIu64" "
 			   "points to block %"PRIu64" which has already been "
 			   "used by another part of the file system. "
 			   "Truncate this chain by deleting this invalid "
@@ -222,11 +223,12 @@
 	if (allowed) {
 		ocfs2_bitmap_test(allowed, blkno, &was_set);
 		if (!was_set &&
-		    prompt(ost, PY, "Chain %d in allocator at inode %"PRIu64" "
-			   "points to block %"PRIu64" which should not be "
-			   "found in the allocator.  Truncate this chain by "
-			   "deleting this invalid block reference?",
+		    prompt(ost, PY, 10, "Chain %d in allocator at inode "
+			   "%"PRIu64" points to block %"PRIu64" which should "
+			   "not be found in the allocator.  Truncate this "
+			   "chain by deleting this invalid block reference?",
 			   cs->cs_chain_no, di->i_blkno, blkno))  {
+
 			cbr->cb_new_next_blkno = 1;
 			/* will set next after reading */
 		} 
@@ -248,10 +250,12 @@
 	}
 
 	if (check_group_desc(ost, di, cs, bg, blkno) &&
-	    prompt(ost, PY, "Chain %d in allocator at inode %"PRIu64" refers "
-		   "to an invalid descriptor block at %"PRIu64".  Truncate "
-		   "the chain by removing this reference?", cs->cs_chain_no,
+	    prompt(ost, PY, 11, "Chain %d in allocator at inode %"PRIu64" "
+		   "refers to an invalid descriptor block at %"PRIu64". "
+		   "Truncate the chain by removing this reference?",
+		   cs->cs_chain_no,
 		   di->i_blkno, blkno)) {
+
 		cbr->cb_new_next_blkno = 1;
 		cbr->cb_next_blkno = 0;
 	}
@@ -356,7 +360,7 @@
 
 	if (cs->cs_total_bits != chain->c_total ||
 	    cs->cs_free_bits != chain->c_free) {
-		if (prompt(ost, PY, "Chain %d in allocator inode %"PRIu64" "
+		if (prompt(ost, PY, 12, "Chain %d in allocator inode %"PRIu64" "
 			   "has %u bits marked free out of %d total bits "
 			   "but the block groups in the chain have %u "
 			   "free out of %u total.  Fix this by updating "
@@ -421,7 +425,7 @@
 
 	/* make sure cl_count is clamped to the size of the inode */
 	if (cl->cl_count > max_count &&
-	    prompt(ost, PY, "Allocator inode %"PRIu64" claims to have %u "
+	    prompt(ost, PY, 4, "Allocator inode %"PRIu64" claims to have %u "
 		   "chains, but the maximum is %u. Fix the inode's count?",
 		   di->i_blkno, cl->cl_count, max_count)) {
 		cl->cl_count = max_count;
@@ -432,10 +436,10 @@
 		max_count = cl->cl_count;
 
 	if (cl->cl_next_free_rec > max_count) {
-		if (prompt(ost, PY, "Allocator inode %"PRIu64" claims %u as "
-			   "the next free chain record, but fsck believes the "
-			   "largest valid value is %u.  Clamp the next record "
-			   "value?", di->i_blkno, cl->cl_next_free_rec,
+		if (prompt(ost, PY, 5, "Allocator inode %"PRIu64" claims %u "
+			   "as the next free chain record, but fsck believes "
+			   "the largest valid value is %u.  Clamp the next "
+			   "record value?", di->i_blkno, cl->cl_next_free_rec,
 			   max_count)) {
 			cl->cl_next_free_rec = cl->cl_count;
 			changed = 1;
@@ -465,7 +469,7 @@
 			continue;
 		}
 
-		if (prompt(ost, PY, "Chain %d in allocator inode %"PRIu64" "
+		if (prompt(ost, PY, 6, "Chain %d in allocator inode %"PRIu64" "
 			   "is empty.  Remove it from the chain record "
 			   "array in the inode and shift further chains "
 			   "into its place?", cs.cs_chain_no, di->i_blkno)) {
@@ -492,7 +496,7 @@
 
 	if (di->id1.bitmap1.i_total != total || 
 	    (di->id1.bitmap1.i_used != total - free)) {
-		if (prompt(ost, PY, "Allocator inode %"PRIu64" has %u bits "
+		if (prompt(ost, PY, 7, "Allocator inode %"PRIu64" has %u bits "
 			   "marked used out of %d total bits but the chains "
 			   "have %u used out of %u total.  Fix this by "
 			   "updating the inode counts?", di->i_blkno,
@@ -581,7 +585,7 @@
 		 * that for now. */
 		ret = check_group_desc(ost, di, &cs, bg, blkno);
 		if (ret == OCFS2_ET_BAD_GROUP_DESC_MAGIC &&
-		    prompt(ost, PY, "Cluster group descriptor at block "
+		    prompt(ost, PY, 2, "Cluster group descriptor at block "
 			   "%"PRIu64" doesn't even have a valid signature. "
 			   "Initialize it and mark it for inclusion in the "
 			   "cluster group chain?", blkno)) {
@@ -617,7 +621,7 @@
 	     !ocfs2_bitmap_find_next_set(bitmap_descs, blkno, &blkno);
 	     blkno++) {
 
-		if (!prompt(ost, PY, "Block %"PRIu64" should be a group "
+		if (!prompt(ost, PY, 3, "Block %"PRIu64" should be a group "
 			    "descriptor for the bitmap chain allocator but it "
 			    "wasn't found in any chains.  Link it into the "
 			    "chain allocator?", blkno))

Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/pass1.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -126,7 +126,7 @@
 		 * bitmap and if the user wants us to keep tracking it and
 		 * write back the new map */
 		if (oldval != val && !ost->ost_write_inode_alloc_asked) {
-			yn = prompt(ost, PY, "fsck found an inode whose "
+			yn = prompt(ost, PY, 0, "fsck found an inode whose "
 				    "allocation does not match the chain "
 				    "allocators.  Fix the allocation of this "
 				    "and all future inodes?");
@@ -151,7 +151,7 @@
 
 	/* make sure the inode's fields are consistent if it's allocated */
 	if (val == 1 && node != (uint16_t)di->i_suballoc_node &&
-	    prompt(ost, PY, "Inode %"PRIu64" indicates that it was allocated "
+	    prompt(ost, PY, 0, "Inode %"PRIu64" indicates that it was allocated "
 		   "from node %"PRIu16" but node %"PRIu16"'s chain allocator "
 		   "covers the inode.  Fix the inode's record of where it is "
 		   "allocated?",
@@ -179,7 +179,7 @@
 		goto out;
 
 	if (di->i_fs_generation != ost->ost_fs_generation) {
-		if (prompt(ost, PY, "Inode read from block %"PRIu64" looks "
+		if (prompt(ost, PY, 0, "Inode read from block %"PRIu64" looks "
 			   "like it is valid but it has a generation of %x "
 			   "that doesn't match the current volume's "
 			   "generation of %x.  This is probably a harmless "
@@ -189,7 +189,7 @@
 			clear = 1;
 			goto out;
 		}
-		if (prompt(ost, PY, "Update the inode's generation to match "
+		if (prompt(ost, PY, 0, "Update the inode's generation to match "
 			  "the volume?")) {
 
 			di->i_fs_generation = ost->ost_fs_generation;
@@ -209,7 +209,7 @@
 	 * fsck can do to fix it up */
 
 	if (di->i_blkno != blkno &&
-	    prompt(ost, PY, "Inode read from block %"PRIu64" has i_blkno set "
+	    prompt(ost, PY, 0, "Inode read from block %"PRIu64" has i_blkno set "
 		   "to %"PRIu64".  Set the inode's i_blkno value to reflect "
 		   "its location on disk?", blkno, di->i_blkno)) {
 		di->i_blkno = blkno;
@@ -223,7 +223,7 @@
 	/* offer to clear a non-directory root inode so that 
 	 * pass3:check_root() can re-create it */
 	if ((di->i_blkno == fs->fs_root_blkno) && !S_ISDIR(di->i_mode) && 
-	    prompt(ost, PY, "Root inode isn't a directory.  Clear it in "
+	    prompt(ost, PY, 0, "Root inode isn't a directory.  Clear it in "
 		   "preparation for fixing it?")) {
 		di->i_dtime = 0ULL;
 		di->i_links_count = 0ULL;
@@ -233,7 +233,7 @@
 		o2fsck_write_inode(ost, blkno, di);
 	}
 
-	if (di->i_dtime && prompt(ost, PY, "Inode %"PRIu64" is in use but has "
+	if (di->i_dtime && prompt(ost, PY, 0, "Inode %"PRIu64" is in use but has "
 				  "a non-zero dtime.  Reset the dtime to 0?",  
 				   di->i_blkno)) {
 		di->i_dtime = 0ULL;
@@ -330,7 +330,7 @@
 		vb->vb_link_read_error);
 
 	if (vb->vb_link_read_error) {
-		if (prompt(ost, PY, "There was an error reading a data block "
+		if (prompt(ost, PY, 0, "There was an error reading a data block "
 			   "for symlink inode %"PRIu64".  Clear the inode?",
 			   di->i_blkno)) {
 			vb->vb_clear = 1;
@@ -340,7 +340,7 @@
 
 	/* XXX this could offer to null terminate */
 	if (!vb->vb_saw_link_null) {
-		if (prompt(ost, PY, "The target of symlink inode %"PRIu64" "
+		if (prompt(ost, PY, 0, "The target of symlink inode %"PRIu64" "
 			   "isn't null terminated.  Clear the inode?",
 			   di->i_blkno)) {
 			vb->vb_clear = 1;
@@ -351,7 +351,7 @@
 	expected = ocfs2_blocks_in_bytes(ost->ost_fs, vb->vb_link_len + 1);
 
 	if (di->i_size != vb->vb_link_len) {
-		if (prompt(ost, PY, "The target of symlink inode %"PRIu64" "
+		if (prompt(ost, PY, 0, "The target of symlink inode %"PRIu64" "
 			   "is %"PRIu64" bytes long on disk, but i_size is "
 			   "%"PRIu64" bytes long.  Update i_size to reflect "
 			   "the length on disk?",
@@ -365,7 +365,7 @@
 	/* maybe we don't shrink link target allocations, I don't know,
 	 * someone will holler if this is wrong :) */
 	if (vb->vb_num_blocks != expected) {
-		if (prompt(ost, PN, "The target of symlink inode %"PRIu64" "
+		if (prompt(ost, PN, 0, "The target of symlink inode %"PRIu64" "
 			   "fits in %"PRIu64" blocks but the inode has "
 			   "%"PRIu64" allocated.  Clear the inode?", 
 			   di->i_blkno, expected, vb->vb_num_blocks)) {
@@ -390,7 +390,7 @@
 		vb->vb_errors++;
 #if 0 /* XXX ext2 does this by returning a value to libext2 which clears the 
 	 block from the inode's allocation */
-		if (prompt(ost, PY, "inode %"PRIu64" references bad physical "
+		if (prompt(ost, PY, 0, "inode %"PRIu64" references bad physical "
 			   "block %"PRIu64" at logical block %"PRIu64", "
 			   "should it be cleared?", di->i_blkno, bklno, 
 			   bcount)) {
@@ -401,7 +401,7 @@
 	/* XXX this logic should be more sophisticated.  It's not really clear
 	 * what ext2 is trying to do in theirs. */
 	if (vb->vb_errors == 12) {
-		if (prompt(ost, PY, "inode %"PRIu64" has seen many errors, "
+		if (prompt(ost, PY, 0, "inode %"PRIu64" has seen many errors, "
 			   "should it be cleared?", di->i_blkno)) {
 			vb->vb_clear = 1;
 			return OCFS2_BLOCK_ABORT;
@@ -477,7 +477,7 @@
 		check_link_data(&vb);
 
 	if (S_ISDIR(di->i_mode) && vb.vb_num_blocks == 0) {
-		if (prompt(ost, PY, "Inode %"PRIu64" is a zero length "
+		if (prompt(ost, PY, 0, "Inode %"PRIu64" is a zero length "
 			   "directory, clear it?", di->i_blkno)) {
 			vb.vb_clear = 1;
 		}
@@ -504,7 +504,7 @@
 
 	/* i_size is checked for symlinks elsewhere */
 	if (!S_ISLNK(di->i_mode) && di->i_size > expected &&
-	    prompt(ost, PY, "Inode %"PRIu64" has a size of %"PRIu64" but has "
+	    prompt(ost, PY, 0, "Inode %"PRIu64" has a size of %"PRIu64" but has "
 		    "%"PRIu64" bytes of actual data. Correct the file size?",
 		    di->i_blkno, di->i_size, expected)) {
 		di->i_size = expected;
@@ -516,7 +516,7 @@
 		expected = ocfs2_clusters_in_blocks(fs, vb.vb_last_block + 1);
 
 	if (di->i_clusters < expected &&
-	    prompt(ost, PY, "inode %"PRIu64" has %"PRIu32" clusters but its "
+	    prompt(ost, PY, 0, "inode %"PRIu64" has %"PRIu32" clusters but its "
 		   "blocks fit in %"PRIu64" clusters.  Correct the number of "
 		   "clusters?", di->i_blkno, di->i_clusters, expected)) {
 		di->i_clusters = expected;
@@ -598,7 +598,7 @@
 
 		if (!ost->ost_write_cluster_alloc_asked) {
 			int yn;
-			yn = prompt(ost, PY, "The cluster bitmap doesn't "
+			yn = prompt(ost, PY, 0, "The cluster bitmap doesn't "
 				    "match what fsck thinks should be in use "
 				    "and freed.  Update the bitmap on disk?");
 			ost->ost_write_cluster_alloc_asked = 1;

Modified: trunk/fsck.ocfs2/pass2.c
===================================================================
--- trunk/fsck.ocfs2/pass2.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/pass2.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -106,7 +106,7 @@
 	if (!expect_dots) {
 	       	if (!dirent_has_dots(dirent, 1) && !dirent_has_dots(dirent, 2))
 			return 0;
-		if (prompt(ost, PY, "Duplicate '%.*s' directory entry found, "
+		if (prompt(ost, PY, 0, "Duplicate '%.*s' directory entry found, "
 			   "remove it?", dirent->name_len, dirent->name)) {
 			dirent->inode = 0;
 			return OCFS2_DIRENT_CHANGED;
@@ -114,7 +114,7 @@
 	}
 
 	if (!dirent_has_dots(dirent, expect_dots) &&
-	    prompt(ost, PY, "The %s directory entry in directory inode "
+	    prompt(ost, PY, 0, "The %s directory entry in directory inode "
 		   "%"PRIu64" is '%.*s' instead of '%.*s'.  Clobber the "
 		   "current name with the expected dot name?", 
 		   expect_dots == 1 ? "first" : "second", dbe->e_ino, 
@@ -143,7 +143,7 @@
 	}
 
 	if ((dirent->inode != dbe->e_ino) &&
-            prompt(ost, PY, "The '.' entry in directory inode %"PRIu64" "
+            prompt(ost, PY, 0, "The '.' entry in directory inode %"PRIu64" "
 		   "points to inode %"PRIu64" instead of itself.  Fix "
 		   "the '.' entry?", dbe->e_ino, dirent->inode)) {
 		dirent->inode = dbe->e_ino;
@@ -157,7 +157,7 @@
 	 */
 	new_len = OCFS2_DIR_REC_LEN(dirent->name_len) - dirent->rec_len;
 	if (new_len && (changed_len || 
-			prompt(ost, PY, "The '.' entry in directory inode "
+			prompt(ost, PY, 0, "The '.' entry in directory inode "
 			       "%"PRIu64" is too long.  Try to create another "
 			       "directory entry from the excess?", 
 			       dbe->e_ino))) {
@@ -185,7 +185,7 @@
 	    (OCFS2_DIR_REC_LEN(dirent->name_len) <= dirent->rec_len))
 		return 0;
 
-	if (!prompt(ost, PY, "Directory inode %"PRIu64" corrupted in logical "
+	if (!prompt(ost, PY, 0, "Directory inode %"PRIu64" corrupted in logical "
 		    "block %"PRIu64" physical block %"PRIu64" offset %d. "
 		    "Attempt to repair this block's directory entries?",
 		    dbe->e_ino, dbe->e_blkcount, dbe->e_blkno, offset))
@@ -233,7 +233,7 @@
 	int len = dirent->name_len, fix = 0, ret_flags = 0;
 
 	if (len == 0) {
-		if (prompt(ost, PY, "Directory entry has a zero-length name, "
+		if (prompt(ost, PY, 0, "Directory entry has a zero-length name, "
 				    "clear it?")) {
 			dirent->inode = 0;
 			ret_flags = OCFS2_DIRENT_CHANGED;
@@ -243,7 +243,7 @@
 	for(; len-- > 0 && (*chr == '/' || *chr == '\0'); chr++) {
 		/* XXX in %s parent name */
 		if (!fix) {
-			fix = prompt(ost, PY, "Directory entry '%.*s' "
+			fix = prompt(ost, PY, 0, "Directory entry '%.*s' "
 				     "contains invalid characters, replace "
 				     "them with dots?", dirent->name_len, 
 				     dirent->name);
@@ -261,7 +261,7 @@
 				struct ocfs2_dir_entry *dirent, int offset)
 {
 	if (ocfs2_block_out_of_range(ost->ost_fs, dirent->inode)) {
-		if (prompt(ost, PY, "Directory entry '%.*s' refers to inode "
+		if (prompt(ost, PY, 0, "Directory entry '%.*s' refers to inode "
 			   "number %"PRIu64" which is out of range, "
 			   "clear the entry?", dirent->name_len, dirent->name, 
 			   dirent->inode)) {
@@ -271,7 +271,7 @@
 	}
 
 	if (!o2fsck_test_inode_allocated(ost, dbe->e_ino) &&
-	    prompt(ost, PY, "Directory entry '%.*s' refers to inode number "
+	    prompt(ost, PY, 0, "Directory entry '%.*s' refers to inode number "
 		   "%"PRIu64" which isn't allocated, clear the entry?", 
 		   dirent->name_len, dirent->name, dirent->inode)) {
 		dirent->inode = 0;
@@ -346,7 +346,7 @@
 
 check:
 	if ((dirent->file_type != expected_type) &&
-	    prompt(ost, PY, "Directory entry %.*s contains file type %s (%u) "
+	    prompt(ost, PY, 0, "Directory entry %.*s contains file type %s (%u) "
 		"but its inode %"PRIu64" leads to type %s (%u).  Reset the "
 		"entry's type to match the inode's?",
 		dirent->name_len, dirent->name, 
@@ -395,7 +395,7 @@
 		return 0;
 	}
 
-	if (prompt(ost, 0, "Directory inode %"PRIu64" is not the first to "
+	if (prompt(ost, 0, 0, "Directory inode %"PRIu64" is not the first to "
 		"claim to be the parent of subdir '%.*s' (inode %"PRIu64"). "
 		"Clear this directory entry and leave the previous parent of "
 		"the subdir's inode intact?", dbe->e_ino, 

Modified: trunk/fsck.ocfs2/pass3.c
===================================================================
--- trunk/fsck.ocfs2/pass3.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/pass3.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -56,7 +56,7 @@
 		return;
 	}
 
-	if (!prompt(ost, PY, "The root inode %"PRIu64" doesn't exist. "
+	if (!prompt(ost, PY, 0, "The root inode %"PRIu64" doesn't exist. "
 			"Should it be created?", ost->ost_fs->fs_root_blkno)) {
 		printf("Aborting.\n");
 		exit(FSCK_ERROR);
@@ -185,7 +185,7 @@
 		/* ok, we hit an orphan subtree with no parent or are at 
 		 * the dir in a subtree that is the first to try to reference
 		 * a dir in its children */
-		fix = prompt(ost, PY, "Directory inode %"PRIu64" isn't "
+		fix = prompt(ost, PY, 0, "Directory inode %"PRIu64" isn't "
 			     "connected to the filesystem.  Move it to "
 			     "lost+found?", dp->dp_ino);
 		if (fix)
@@ -195,7 +195,7 @@
 	}
 
 	if (dir->dp_dirent != dir->dp_dot_dot) {
-		fix = prompt(ost, PY, "Directory inode %"PRIu64" is "
+		fix = prompt(ost, PY, 0, "Directory inode %"PRIu64" is "
 			     "referenced by a dirent in directory %"PRIu64" "
 			     "but its '..' entry points to inode %"PRIu64". "
 			     "Fix the '..' entry to reference %"PRIu64"?", 

Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/pass4.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -51,7 +51,7 @@
 
 	/* XXX offer to remove files/dirs with no data? */
 	if (refs == 0 &&
-	    prompt(ost, PY, "Inode %"PRIu64" isn't referenced by any "
+	    prompt(ost, PY, 0, "Inode %"PRIu64" isn't referenced by any "
 		   "directory entries.  Move it to lost+found?", 
 		   di->i_blkno)) {
 		o2fsck_reconnect_file(ost, blkno);
@@ -74,7 +74,7 @@
 			"disk it is %"PRIu16, di->i_blkno, in_inode, 
 			di->i_links_count);
 
-	if (prompt(ost, PY, "Inode %"PRIu64" has a link count of %"PRIu16" on "
+	if (prompt(ost, PY, 0, "Inode %"PRIu64" has a link count of %"PRIu16" on "
 		   "disk but directory entry references come to %"PRIu16". "
 		   "Update the count on disk to match?", di->i_blkno, in_inode, 
 		   refs)) {

Modified: trunk/fsck.ocfs2/problem.c
===================================================================
--- trunk/fsck.ocfs2/problem.c	2004-11-20 04:30:53 UTC (rev 432)
+++ trunk/fsck.ocfs2/problem.c	2004-11-23 00:17:57 UTC (rev 433)
@@ -20,7 +20,7 @@
  * --
  *
  * prompt() asks the user whether a given problem should be fixed or not.
- * "problem.c" is derived from the baroque e2fsck origins for this concept.
+ * "problem.c" is derived from the baroque e2fsck origins of this concept.
  *
  * XXX
  * 	The significant gap here is in persistent answers.  Often one wants
@@ -146,12 +146,11 @@
  * and have a notion of grouping, as well.  The caller is expected to provide
  * a fully formed question that isn't terminated with a newline.
  */
-int prompt(o2fsck_state *ost, unsigned flags, const char *fmt, ...)
+int prompt(o2fsck_state *ost, unsigned flags, unsigned code, const char *fmt,
+	   ...)
 {
 	va_list ap;
 	int c, ans = 0;
-	static char fatal[] = " If you answer no fsck will not be able to "
-			      "continue and will exit.";
 	static char yes[] = " <y> ", no[] = " <n> ";
 	char *output;
 	size_t len, part;
@@ -169,11 +168,8 @@
 		exit(FSCK_ERROR);
 	}
 
-	if (flags & PF)
-		len += sizeof(fatal); /* includes null */
-
 	if (flags & (PY|PN))
-		len += sizeof(yes); /* includes null */
+		len += sizeof(yes) + 10; /* includes code and null */
 
 	output = malloc(len);
 	if (output == NULL) {
@@ -181,8 +177,15 @@
 		exit(FSCK_ERROR);
 	}
 
+	part = snprintf(output, len, "[%.6u] ", code);
+	if (part < 0) {
+		perror("vsnprintf failed when trying to bulid an output "
+		       "buffer");
+		exit(FSCK_ERROR);
+	}
+
 	va_start(ap, fmt);
-	part = vsnprintf(output, len, fmt, ap);
+	part = vsnprintf(output + part, len - part, fmt, ap);
 	va_end(ap);
 	if (part < 0) {
 		perror("vsnprintf failed when trying to bulid an output "
@@ -190,9 +193,6 @@
 		exit(FSCK_ERROR);
 	}
 
-	if (flags & PF)
-		strcat(output, fatal);
-
 	if (!ost->ost_ask) {
 		ans = ost->ost_answer ? 'y' : 'n';
 	} else {
@@ -247,10 +247,5 @@
 	else
 		printf("%c\n", ans);
 
-	if (flags & PF) {
-		printf("fsck cannot continue.  Exiting.\n");
-		exit(FSCK_ERROR);
-	}
-
 	return ans == 'y';
 }



More information about the Ocfs2-tools-commits mailing list