[Ocfs2-tools-devel] [PATCH 21/30] fsck.ocfs2: verify dirent -> dx entry linkages

Mark Fasheh mfasheh at suse.com
Wed Apr 28 18:26:26 PDT 2010


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>
Cc: Joel Becker <joel.becker at oracle.com>
Cc: Sunil Mushran <sunil.mushran at oracle.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