[Ocfs2-tools-commits] zab commits r1049 - trunk/fsck.ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Aug 16 16:55:44 CDT 2005


Author: zab
Signed-off-by: manish
Date: 2005-08-16 16:55:43 -0500 (Tue, 16 Aug 2005)
New Revision: 1049

Modified:
   trunk/fsck.ocfs2/pass1.c
   trunk/fsck.ocfs2/pass4.c
Log:
o allow fsck to recognize situations where an inode which has an 
  i_count doesn't have directory entry references, or vice versa.
  This condition shouldn't be considered a failure at all.

Signed-off-by: manish


Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c	2005-08-16 01:05:05 UTC (rev 1048)
+++ trunk/fsck.ocfs2/pass1.c	2005-08-16 21:55:43 UTC (rev 1049)
@@ -533,6 +533,12 @@
 	if (clear) {
 		di->i_flags &= ~OCFS2_VALID_FL;
 		o2fsck_write_inode(ost, blkno, di);
+		/* if we cleared the inode then we're going to be 
+		 * forbidding directory entries from referencing it.. we
+		 * should back-out the inode count we found in the inode
+		 * so that we're not surprised when there aren't any
+		 * references to it in pass 4 */
+		o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno, 0);
 	}
 }
 

Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c	2005-08-16 01:05:05 UTC (rev 1048)
+++ trunk/fsck.ocfs2/pass4.c	2005-08-16 21:55:43 UTC (rev 1049)
@@ -40,8 +40,8 @@
 
 static const char *whoami = "pass4";
 
-static errcode_t check_link_counts(o2fsck_state *ost, ocfs2_dinode *di,
-				   uint64_t blkno)
+static void check_link_counts(o2fsck_state *ost, ocfs2_dinode *di,
+			      uint64_t blkno)
 {
 	uint16_t refs, in_inode;
 	errcode_t ret;
@@ -67,7 +67,9 @@
 	ret = ocfs2_read_inode(ost->ost_fs, blkno, (char *)di);
 	if (ret) {
 		com_err(whoami, ret, "reading inode %"PRIu64" to update its "
-			"i_links_count", blkno);
+			"i_links_count.  Could this be because a directory "
+			"entry referenced an invalid inode but wasn't fixed?",
+			blkno);
 		goto out;
 	}
 
@@ -89,7 +91,7 @@
 	}
 
 out:
-	return 0;
+	return;
 }
 
 static int replay_orphan_iterate(struct ocfs2_dir_entry *dirent,
@@ -180,12 +182,43 @@
 	return ret;
 }
 
+/* return the next inode that has either directory entries pointing to it or
+ * that was valid and had a non-zero i_links_count.  OCFS2_ET_BIT_NOT_FOUND
+ * will be bubbled up from the next_blkno() calls when there is no such next
+ * inode.  It is expected that sometimes these won't match.  If a directory
+ * has been lost there can be inodes with i_links_count and no directory
+ * entries at all.  If an inode was lost but the user chose not to erase
+ * the directory entries then there may be references to inodes that
+ * we never saw the i_links_count for */
+static errcode_t next_inode_any_ref(o2fsck_state *ost, uint64_t start,
+				    uint64_t *blkno_ret)
+{
+	errcode_t tmp, ret = OCFS2_ET_BIT_NOT_FOUND;
+	uint64_t blkno;
+
+	tmp = o2fsck_icount_next_blkno(ost->ost_icount_refs, start, &blkno);
+	if (tmp == 0) {
+		*blkno_ret = blkno;
+		ret = 0;
+	}
+
+	tmp = o2fsck_icount_next_blkno(ost->ost_icount_in_inodes, start,
+				       &blkno);
+	/* use this if we didn't have one yet or this one's lesser */
+	if (tmp == 0 && (ret != 0 || (blkno < *blkno_ret))) {
+		ret = 0;
+		*blkno_ret = blkno;
+	}
+
+	return ret;
+}
+
 errcode_t o2fsck_pass4(o2fsck_state *ost)
 {
 	ocfs2_dinode *di;
 	char *buf = NULL;
-	errcode_t ret, ref_ret, inode_ret;
-	uint64_t blkno, ref_blkno, inode_blkno;
+	errcode_t ret;
+	uint64_t blkno, start;
 
 	printf("Pass 4a: checking for orphaned inodes\n");
 
@@ -205,31 +238,11 @@
 	}
 
 	di = (ocfs2_dinode *)buf;
+	start = 0;
 
-	for(blkno = 0, ref_ret = 0; ref_ret != OCFS2_ET_BIT_NOT_FOUND ;
-	    blkno = ref_blkno + 1) {
-		ref_blkno = 0;
-		ref_ret = o2fsck_icount_next_blkno(ost->ost_icount_refs, blkno,
-						   &ref_blkno);
-		inode_blkno = 0;
-		inode_ret = o2fsck_icount_next_blkno(ost->ost_icount_in_inodes,
-						     blkno, &inode_blkno);
-
-		verbosef("ref %"PRIu64" ino %"PRIu64"\n", ref_blkno,
-			 inode_blkno);
-
-		if (ref_ret != inode_ret || ref_blkno != inode_blkno) {
-			printf("fsck's internal inode link count tracking "
-			       "isn't consistent. (ref_ret = %d ref_blkno = "
-			       "%"PRIu64" inode_ret = %d inode_blkno = "
-			       "%"PRIu64")\n", (int)ref_ret, ref_blkno,
-			       (int)inode_ret, inode_blkno);
-			ret = OCFS2_ET_INTERNAL_FAILURE;
-			break;
-		}
-
-		if (ref_ret == 0)
-			check_link_counts(ost, di, ref_blkno);
+	while (next_inode_any_ref(ost, start, &blkno) == 0) {
+		check_link_counts(ost, di, blkno);
+		start = blkno + 1;
 	}
 
 out:



More information about the Ocfs2-tools-commits mailing list