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

Mark Fasheh mfasheh at suse.com
Thu Apr 29 16:15:49 PDT 2010


On Thu, Apr 29, 2010 at 03:13:17PM -0700, Joel Becker wrote:
> On Wed, Apr 28, 2010 at 06:26:26PM -0700, Mark Fasheh wrote:
> > 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.
> 
> 	This doesn't quite read right.  I think the middle sentence is
> extraneous.  Do you mean:
> 
> A directory entry is missing an entry in the directory index.  The
> missing index entry will cause lookups on this name to fail.

Ugh, too much late-night coding  :)


> > 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;
> 
> 	Print the name: "missing an index for the entry \"%.*s\" (inode
> %"PRIu64")".  The index is about looking up the name; the inode number
> is almost extraneous.

Updated patch follows.
	--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 |    6 +++++
 fsck.ocfs2/pass2.c                |   39 +++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index 5cda023..5bea432 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -1061,6 +1061,12 @@ file system.
 
 Answering yes will truncate the invalid index.
 
+.SS "DX_LOOKUP_FAILED"
+A directory entry is missing an entry in the 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 06cd465..4b43a22 100644
--- a/fsck.ocfs2/pass2.c
+++ b/fsck.ocfs2/pass2.c
@@ -648,6 +648,41 @@ 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 the file \"%.*s\""
+				   " (inode # %"PRIu64")\n. Repair this by "
+				   "rebuilding the directory index?",
+				   dbe->e_ino, dirent->name_len, dirent->name,
+				   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 +840,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