[Ocfs2-tools-commits] zab commits r1053 -
branches/ocfs2-tools-1.0/fsck.ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Aug 18 11:51:11 CDT 2005
Author: zab
Date: 2005-08-18 11:51:09 -0500 (Thu, 18 Aug 2005)
New Revision: 1053
Modified:
branches/ocfs2-tools-1.0/fsck.ocfs2/pass1.c
branches/ocfs2-tools-1.0/fsck.ocfs2/pass4.c
Log:
merge commit 1049 from trunk:
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.
Modified: branches/ocfs2-tools-1.0/fsck.ocfs2/pass1.c
===================================================================
--- branches/ocfs2-tools-1.0/fsck.ocfs2/pass1.c 2005-08-18 16:49:45 UTC (rev 1052)
+++ branches/ocfs2-tools-1.0/fsck.ocfs2/pass1.c 2005-08-18 16:51:09 UTC (rev 1053)
@@ -530,6 +530,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: branches/ocfs2-tools-1.0/fsck.ocfs2/pass4.c
===================================================================
--- branches/ocfs2-tools-1.0/fsck.ocfs2/pass4.c 2005-08-18 16:49:45 UTC (rev 1052)
+++ branches/ocfs2-tools-1.0/fsck.ocfs2/pass4.c 2005-08-18 16:51:09 UTC (rev 1053)
@@ -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