forked from pool/ocfs2-tools
c8700c5230
OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/ocfs2-tools?expand=0&rev=8
93 lines
2.9 KiB
Diff
93 lines
2.9 KiB
Diff
From 4c1cf61779ee71c828134d956f5779e272a3195e Mon Sep 17 00:00:00 2001
|
|
From: Mark Fasheh <mfasheh@suse.com>
|
|
Date: Fri, 23 Apr 2010 23:09:05 -0700
|
|
Subject: [PATCH 21/30] 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@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.7.0.2
|
|
|