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

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Fri Nov 19 00:03:20 CST 2004


Author: zab
Date: 2004-11-19 00:03:18 -0600 (Fri, 19 Nov 2004)
New Revision: 423

Modified:
   trunk/fsck.ocfs2/icount.c
   trunk/fsck.ocfs2/include/icount.h
   trunk/fsck.ocfs2/pass4.c
Log:
o iterate over the icount structures themselves in pass 4 instead of scanning
  the inode groups again.  this cut the fsck time in half on an fs with 
  a built kernel tree.


Modified: trunk/fsck.ocfs2/icount.c
===================================================================
--- trunk/fsck.ocfs2/icount.c	2004-11-19 05:59:26 UTC (rev 422)
+++ trunk/fsck.ocfs2/icount.c	2004-11-19 06:03:18 UTC (rev 423)
@@ -64,21 +64,25 @@
 	rb_insert_color(&in->in_node, &icount->ic_multiple_tree);
 }
 
-static icount_node *icount_search(o2fsck_icount *icount, uint64_t blkno)
+static icount_node *icount_search(o2fsck_icount *icount, uint64_t blkno,
+				  icount_node **next)
 {
 	struct rb_node *node = icount->ic_multiple_tree.rb_node;
-	icount_node *in;
+	icount_node *in, *last_left = NULL;
 
 	while (node) {
 		in = rb_entry(node, icount_node, in_node);
 
-		if (blkno < in->in_blkno)
+		if (blkno < in->in_blkno) {
+			last_left = in;
 			node = node->rb_left;
-		else if (blkno > in->in_blkno)
+		} else if (blkno > in->in_blkno)
 			node = node->rb_right;
 		else
 			return in;
 	}
+	if (next && last_left)
+		*next = last_left;
 	return NULL;
 }
 
@@ -93,7 +97,7 @@
 	else
 		ocfs2_bitmap_clear(icount->ic_single_bm, blkno, NULL);
 
-	in = icount_search(icount, blkno);
+	in = icount_search(icount, blkno, NULL);
 	if (in) {
 		if (count < 2) {
 			rb_erase(&in->in_node, &icount->ic_multiple_tree);
@@ -125,7 +129,7 @@
 		goto out;
 	}
 
-	in = icount_search(icount, blkno);
+	in = icount_search(icount, blkno, NULL);
 	if (in)
 		ret = in->in_icount;
 
@@ -150,7 +154,7 @@
 	if (was_set) {
 		prev_count = 1;
 	} else {
-		in = icount_search(icount, blkno);
+		in = icount_search(icount, blkno, NULL);
 		if (in == NULL)
 			prev_count = 0;
 		else
@@ -188,6 +192,35 @@
 	return 0;
 }
 
+errcode_t o2fsck_icount_next_blkno(o2fsck_icount *icount, uint64_t start,
+				   uint64_t *found)
+{
+	uint64_t next_bit;
+	errcode_t ret;
+	icount_node *in, *next = NULL;
+
+	ret = ocfs2_bitmap_find_next_set(icount->ic_single_bm, start,
+						  &next_bit);
+
+	in = icount_search(icount, start, &next);
+	if (in == NULL)
+		in = next;
+
+	if (in) {
+		if (ret == OCFS2_ET_BIT_NOT_FOUND)
+			*found = in->in_blkno;
+		else
+			*found = next_bit < in->in_blkno ? next_bit :
+							   in->in_blkno;
+		ret = 0;
+	}
+	else {
+		if (ret != OCFS2_ET_BIT_NOT_FOUND)
+			*found = next_bit;
+	}
+	return ret;
+}
+
 void o2fsck_icount_free(o2fsck_icount *icount)
 {
 	struct rb_node *node;

Modified: trunk/fsck.ocfs2/include/icount.h
===================================================================
--- trunk/fsck.ocfs2/include/icount.h	2004-11-19 05:59:26 UTC (rev 422)
+++ trunk/fsck.ocfs2/include/icount.h	2004-11-19 06:03:18 UTC (rev 423)
@@ -38,6 +38,8 @@
 void o2fsck_icount_free(o2fsck_icount *icount);
 void o2fsck_icount_delta(o2fsck_icount *icount, uint64_t blkno, 
 			 int delta);
+errcode_t o2fsck_icount_next_blkno(o2fsck_icount *icount, uint64_t start,
+				   uint64_t *found);
 
 #endif /* __O2FSCK_ICOUNT_H__ */
 

Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c	2004-11-19 05:59:26 UTC (rev 422)
+++ trunk/fsck.ocfs2/pass4.c	2004-11-19 06:03:18 UTC (rev 423)
@@ -38,28 +38,36 @@
 
 static const char *whoami = "pass4";
 
-static errcode_t check_link_counts(o2fsck_state *ost, ocfs2_dinode *di)
+static errcode_t check_link_counts(o2fsck_state *ost, ocfs2_dinode *di,
+				   uint64_t blkno)
 {
 	uint16_t refs, in_inode;
+	errcode_t ret;
 
-	refs = o2fsck_icount_get(ost->ost_icount_refs, di->i_blkno);
-	in_inode = o2fsck_icount_get(ost->ost_icount_in_inodes, di->i_blkno);
+	refs = o2fsck_icount_get(ost->ost_icount_refs, blkno);
+	in_inode = o2fsck_icount_get(ost->ost_icount_in_inodes, blkno);
 
-	verbosef("ino %"PRIu64", refs %u in %u\n", di->i_blkno, refs, 
-		 in_inode);
+	verbosef("ino %"PRIu64", refs %u in %u\n", blkno, refs, in_inode);
 
 	/* XXX offer to remove files/dirs with no data? */
 	if (refs == 0 &&
 	    prompt(ost, PY, "Inode %"PRIu64" isn't referenced by any "
 		   "directory entries.  Move it to lost+found?", 
 		   di->i_blkno)) {
-		o2fsck_reconnect_file(ost, di->i_blkno);
-		refs = o2fsck_icount_get(ost->ost_icount_refs, di->i_blkno);
+		o2fsck_reconnect_file(ost, blkno);
+		refs = o2fsck_icount_get(ost->ost_icount_refs, blkno);
 	}
 
 	if (refs == in_inode)
 		goto out;
 
+	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);
+		goto out;
+	}
+
 	if (in_inode != di->i_links_count)
 		com_err(whoami, OCFS2_ET_INTERNAL_FAILURE, "fsck's thinks "
 			"inode %"PRIu64" has a link count of %"PRIu16" but on "
@@ -84,9 +92,8 @@
 {
 	ocfs2_dinode *di;
 	char *buf = NULL;
-	errcode_t ret;
-	ocfs2_inode_scan *scan;
-	uint64_t blkno;
+	errcode_t ret, ref_ret, inode_ret;
+	uint64_t blkno, ref_blkno, inode_blkno;
 
 	printf("Pass 4: Checking inodes link counts.\n");
 
@@ -98,38 +105,32 @@
 
 	di = (ocfs2_dinode *)buf;
 
-	ret = ocfs2_open_inode_scan(ost->ost_fs, &scan);
-	if (ret) {
-		com_err(whoami, ret,
-			"while opening inode scan");
-		goto out_free;
-	}
+	for(blkno = 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);
 
-	for(;;) {
-		ret = ocfs2_get_next_inode(scan, &blkno, buf);
-		if (ret) {
-			com_err(whoami, ret, "while reading next inode");
+		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\n");
+			ret = OCFS2_ET_INTERNAL_FAILURE;
 			break;
 		}
-		if (blkno == 0)
-			break;
 
-		if (!(di->i_flags & OCFS2_VALID_FL))
-			continue;
-
-		/*
-		 * XXX e2fsck skips some inodes by their presence in other
-		 * bitmaps.  I think we should use this loop to verify their
-		 * i_links_count as well and just make sure that we update refs
-		 * to match our expectations in previous passes.
-		 */
-
-		check_link_counts(ost, di);
+		if (ref_ret == 0)
+			check_link_counts(ost, di, ref_blkno);
 	}
 
-	ocfs2_close_inode_scan(scan);
-out_free:
-	ocfs2_free(&buf);
 out:
+	if (buf)
+		ocfs2_free(&buf);
+
 	return ret;
 }



More information about the Ocfs2-tools-commits mailing list