[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