[Ocfs2-tools-devel] [PATCH 08/15] dx_dirs v11: fsck.ocfs2 support

Mark Fasheh mfasheh at suse.com
Sat Apr 24 00:42:08 PDT 2010


On Fri, Apr 23, 2010 at 03:49:31PM -0700, Sunil Mushran wrote:
> Coly, I don't see code that detects and fixes corrupt indexes. Am
> I right or am I reading it incorrectly?

It doesn't right now. I had a little time and cooked up an untested (it
compiles though!) patch to do some basic verification. It's attached for
comment. Basically though it just catches the most 'obvious' corruption - a
dirent missing an index entry.

In the future, we should verify linkage the other way around too. That would
help us purge the tree of 'lost' records.
	--mark

--
Mark Fasheh


From: Mark Fasheh <mfasheh at suse.com>

fsck.ocfs2: verify dirent -> dx entry linkages

During pass2 we can trivially do a lookup on dirents while walking the
directory tree. This will help us make sure that an index entry exists for
each dirent. If an entry is not found, the users is prompted and the parent
directory will be marked for an index rebuild.

Signed-off-by: Mark Fasheh <mfasheh at suse.com>
---
 fsck.ocfs2/fsck.ocfs2.checks.8.in |    7 +++++++
 fsck.ocfs2/pass2.c                |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index 5cda023..cfbb12e 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -1061,6 +1061,13 @@ file system.
 
 Answering yes will truncate the invalid index.
 
+.SS "DX_LOOKUP_FAILED"
+A directory entry is missing an entry in the directory index. Not
+found in directory index. The missing index entry will cause lookups
+on this name to fail.
+
+Answering yes will rebuild the directory index, restoring the missing entry.
+
 .SH "SEE ALSO"
 .BR fsck.ocfs2(8)
 
diff --git a/fsck.ocfs2/pass2.c b/fsck.ocfs2/pass2.c
index b999761..e03bd4e 100644
--- a/fsck.ocfs2/pass2.c
+++ b/fsck.ocfs2/pass2.c
@@ -648,6 +648,39 @@ out:
 	return ret;
 }
 
+static errcode_t fix_dirent_index(o2fsck_dirblock_entry *dbe,
+				  struct dirblock_data *dd,
+				  struct ocfs2_dir_entry *dirent,
+				  unsigned int *flags)
+{
+	errcode_t ret = 0;
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *)dd->inoblock_buf;
+	uint64_t ino;
+
+	if (!ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)))
+		goto out;
+
+	if (di->i_dyn_features  & OCFS2_INDEXED_DIR_FL) {
+		ret = ocfs2_lookup(dd->fs, dbe->e_ino, dirent->name,
+				   dirent->name_len, NULL, &ino);
+		if (ret) {
+			if (ret != OCFS2_ET_FILE_NOT_FOUND)
+				goto out;
+			ret = 0;
+
+			if (prompt(dd->ost, PY, PR_DX_LOOKUP_FAILED,
+				   "Directory inode %"PRIu64" is missing "
+				   "an index entry for child inode %"PRIu64
+				   "\n. Repair this by rebuilding the "
+				   "directory index?", dbe->e_ino, ino))
+				*flags |= OCFS2_DIRENT_CHANGED;
+			goto out;
+		}
+	}
+out:
+	return ret;
+}
+
 static int corrupt_dirent_lengths(struct ocfs2_dir_entry *dirent, int left)
 {
 	if ((dirent->rec_len >= OCFS2_DIR_REC_LEN(1)) &&
@@ -805,6 +838,10 @@ static unsigned pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
 		if (dirent->inode == 0)
 			goto next;
 
+		ret = fix_dirent_index(dbe, dd, dirent, &ret_flags);
+		if (ret)
+			goto out;
+
 		verbosef("dirent %.*s refs ino %"PRIu64"\n", dirent->name_len,
 				dirent->name, (uint64_t)dirent->inode);
 		o2fsck_icount_delta(dd->ost->ost_icount_refs, dirent->inode, 1);
-- 
1.6.4.2




More information about the Ocfs2-tools-devel mailing list