[Ocfs2-tools-commits] zab commits r304 - in trunk/fsck.ocfs2: . include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Sep 30 19:24:11 CDT 2004


Author: zab
Date: 2004-09-30 19:24:08 -0500 (Thu, 30 Sep 2004)
New Revision: 304

Added:
   trunk/fsck.ocfs2/include/strings.h
   trunk/fsck.ocfs2/strings.c
Modified:
   trunk/fsck.ocfs2/Makefile
   trunk/fsck.ocfs2/fsck.c
   trunk/fsck.ocfs2/include/fsck.h
   trunk/fsck.ocfs2/pass2.c
Log:
o add a trivial string registry
o discover duplicate dir entries in a block and file the dir inode for 
  rebuilding in pass3


Modified: trunk/fsck.ocfs2/Makefile
===================================================================
--- trunk/fsck.ocfs2/Makefile	2004-09-30 23:14:07 UTC (rev 303)
+++ trunk/fsck.ocfs2/Makefile	2004-10-01 00:24:08 UTC (rev 304)
@@ -29,6 +29,7 @@
 		pass1.c 	\
 		pass2.c 	\
 		problem.c 	\
+		strings.c 	\
 		util.c
 
 HFILES = 	include/fsck.h		\
@@ -38,6 +39,7 @@
 		include/pass1.h		\
 		include/pass2.h		\
 		include/problem.h	\
+		include/strings.h	\
 		include/util.h
 
 OBJS = $(subst .c,.o,$(CFILES))

Modified: trunk/fsck.ocfs2/fsck.c
===================================================================
--- trunk/fsck.ocfs2/fsck.c	2004-09-30 23:14:07 UTC (rev 303)
+++ trunk/fsck.ocfs2/fsck.c	2004-10-01 00:24:08 UTC (rev 304)
@@ -119,6 +119,13 @@
 		return ret;
 	}
 
+	ret = ocfs2_block_bitmap_new(fs, "directory inodes to rebuild",
+				     &ost->ost_rebuild_dirs);
+	if (ret) {
+		com_err(whoami, ret, "while allocating rebuild dirs bitmap");
+		return ret;
+	}
+
 	return 0;
 }
 

Modified: trunk/fsck.ocfs2/include/fsck.h
===================================================================
--- trunk/fsck.ocfs2/include/fsck.h	2004-09-30 23:14:07 UTC (rev 303)
+++ trunk/fsck.ocfs2/include/fsck.h	2004-10-01 00:24:08 UTC (rev 304)
@@ -38,6 +38,8 @@
 	ocfs2_bitmap	*ost_found_blocks;
 	ocfs2_bitmap	*ost_dup_blocks;
 
+	ocfs2_bitmap	*ost_rebuild_dirs;
+
 	o2fsck_icount	*ost_icount_in_inodes;
 	o2fsck_icount	*ost_icount_refs;
 

Added: trunk/fsck.ocfs2/include/strings.h
===================================================================
--- trunk/fsck.ocfs2/include/strings.h	2004-09-30 23:14:07 UTC (rev 303)
+++ trunk/fsck.ocfs2/include/strings.h	2004-10-01 00:24:08 UTC (rev 304)
@@ -0,0 +1,39 @@
+/*
+ * strings.h
+ *
+ * Copyright (C) 2002 Oracle Corporation.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Zach Brown
+ */
+
+#ifndef __O2FSCK_STRINGS_H__
+#define __O2FSCK_STRINGS_H__
+
+#include "ocfs2.h"
+
+typedef struct _o2fsck_strings {
+	struct rb_root	s_root;
+} o2fsck_strings;
+
+errcode_t o2fsck_strings_insert(o2fsck_strings *strings, char *string,
+				size_t strlen, int *is_dup);
+void o2fsck_strings_init(o2fsck_strings *strings);
+void o2fsck_strings_free(o2fsck_strings *strings);
+
+#endif /* __O2FSCK_STRINGS_H__ */
+

Modified: trunk/fsck.ocfs2/pass2.c
===================================================================
--- trunk/fsck.ocfs2/pass2.c	2004-09-30 23:14:07 UTC (rev 303)
+++ trunk/fsck.ocfs2/pass2.c	2004-10-01 00:24:08 UTC (rev 304)
@@ -34,6 +34,7 @@
 #include "fsck.h"
 #include "pass2.h"
 #include "problem.h"
+#include "strings.h"
 #include "util.h"
 
 struct dirblock_data {
@@ -335,6 +336,41 @@
 	return 0;
 }
 
+static int fix_dirent_dups(o2fsck_state *ost, o2fsck_dirblock_entry *dbe,
+			   struct ocfs2_dir_entry *dirent, 
+			   o2fsck_strings *strings, int *dups_in_block)
+{
+	errcode_t err;
+	int was_set;
+
+	if (*dups_in_block)
+		return 0;
+
+	/* does this need to be fatal?  It appears e2fsck just ignores
+	 * the error. */
+	err = o2fsck_strings_insert(strings, dirent->name, dirent->name_len, 
+				   &was_set);
+	if (err)
+		fatal_error(err, "while allocating space to find duplicate "
+				"directory entries");
+
+	if (!was_set)
+		return 0;
+
+	fprintf(stderr, "Duplicate directory entry '%*s' found.\n",
+		      dirent->name_len, dirent->name);
+	fprintf(stderr, "Marking its parent %"PRIu64" for rebuilding.\n",
+			dbe->e_ino);
+
+	err = ocfs2_bitmap_test(ost->ost_rebuild_dirs, dbe->e_ino, &was_set);
+	if (err)
+		fatal_error(err, "while checking for inode %"PRIu64" in "
+				"the used bitmap", dbe->e_ino);
+
+	*dups_in_block = 1;
+	return 0;
+}
+
 /* this could certainly be more clever to issue reads in groups */
 static unsigned pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe, 
 					void *priv_data) 
@@ -342,7 +378,8 @@
 	struct dirblock_data *dd = priv_data;
 	struct ocfs2_dir_entry *dirent, *prev = NULL;
 	unsigned int offset = 0, this_flags, ret_flags = 0;
-	int was_set;
+	o2fsck_strings strings;
+	int was_set, dups_in_block = 0;
 	errcode_t retval;
 
 	retval = ocfs2_bitmap_test(dd->ost->ost_used_inodes, dbe->e_ino, 
@@ -363,6 +400,8 @@
 	printf("found %"PRIu64" %"PRIu64" %"PRIu64"\n", dbe->e_ino, 
 			dbe->e_blkno, dbe->e_blkcount);
 
+	o2fsck_strings_init(&strings);
+
 	while (offset < dd->fs->fs_blocksize) {
 		dirent = (struct ocfs2_dir_entry *)(dd->buf + offset);
 
@@ -385,17 +424,17 @@
 
 		ret_flags |= fix_dirent_dots(dd->ost, dbe, dirent, offset, 
 					     dd->fs->fs_blocksize - offset);
-
 		ret_flags |= fix_dirent_name(dd->ost, dbe, dirent, offset);
-
 		ret_flags |= fix_dirent_filetype(dd->ost, dbe, dirent, offset);
-
 		ret_flags |= fix_dirent_linkage(dd->ost, dbe, dirent, offset);
+		ret_flags |= fix_dirent_dups(dd->ost, dbe, dirent, &strings,
+					     &dups_in_block);
 
 		offset += dirent->rec_len;
 		prev = dirent;
 	}
 
+	o2fsck_strings_free(&strings);
 	return ret_flags;
 }
 

Added: trunk/fsck.ocfs2/strings.c
===================================================================
--- trunk/fsck.ocfs2/strings.c	2004-09-30 23:14:07 UTC (rev 303)
+++ trunk/fsck.ocfs2/strings.c	2004-10-01 00:24:08 UTC (rev 304)
@@ -0,0 +1,109 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * strings.c
+ *
+ * As always, we let e2fsck lead the way.  A bitmap for
+ * inodes with a single i_count (the vast majority), and a
+ * tree of inode numbers with a greater count. 
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2,  as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Zach Brown
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "ocfs2.h"
+
+#include "fsck.h"
+#include "strings.h"
+#include "util.h"
+
+struct string_entry {
+	struct rb_node	s_node;
+	size_t		s_strlen;
+	char		s_string[0]; /* null terminated */
+};
+
+errcode_t o2fsck_strings_insert(o2fsck_strings *strings, char *string,
+			   size_t strlen, int *is_dup)
+{
+	struct rb_node ** p = &strings->s_root.rb_node;
+	struct rb_node * parent = NULL;
+	struct string_entry *se;
+	int cmp;
+
+	*is_dup = 0;
+
+	while (*p)
+	{
+		parent = *p;
+		se = rb_entry(parent, struct string_entry, s_node);
+
+		/* we don't actually care about lexographical sorting */
+		cmp = strlen - se->s_strlen;
+		if (cmp == 0)
+			cmp = memcmp(string, se->s_string, strlen);
+
+#if 0
+		printf("%.*s %s %.*s\n", (int)strlen, string, 
+			cmp < 0 ? "<" : (cmp > 0 ? ">" : "==" ),
+			(int)se->s_strlen, se->s_string);
+#endif
+
+		if (cmp < 0)
+			p = &(*p)->rb_left;
+		else if (cmp > 0)
+			p = &(*p)->rb_right;
+		else {
+			*is_dup = 1;
+			return 0;
+		}
+	}
+
+	se = malloc(offsetof(struct string_entry, s_string[strlen]));
+	if (se == NULL)
+		return OCFS2_ET_NO_MEMORY;
+
+	se->s_strlen = strlen;
+	memcpy(se->s_string, string, strlen);
+
+	rb_link_node(&se->s_node, parent, p);
+	rb_insert_color(&se->s_node, &strings->s_root);
+
+	return 0;
+}
+
+void o2fsck_strings_init(o2fsck_strings *strings)
+{
+	strings->s_root = RB_ROOT;
+}
+
+void o2fsck_strings_free(o2fsck_strings *strings)
+{
+	struct string_entry *se;
+	struct rb_node *node;
+
+	while((node = rb_first(&strings->s_root)) != NULL) {
+		se = rb_entry(node, struct string_entry, s_node);
+		rb_erase(node, &strings->s_root);
+		free(se);
+	}
+}



More information about the Ocfs2-tools-commits mailing list