[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