[Ocfs2-tools-commits] zab commits r246 - in trunk/fsck.ocfs2: .
include
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Sep 21 16:51:08 CDT 2004
Author: zab
Date: 2004-09-21 16:51:06 -0500 (Tue, 21 Sep 2004)
New Revision: 246
Added:
trunk/fsck.ocfs2/fsck.c
trunk/fsck.ocfs2/include/
trunk/fsck.ocfs2/include/fsck.h
trunk/fsck.ocfs2/include/pass1.h
trunk/fsck.ocfs2/pass1.c
Modified:
trunk/fsck.ocfs2/Makefile
Log:
o Add a skeletal fsck so smarter people can point me in the right direction.
Modified: trunk/fsck.ocfs2/Makefile
===================================================================
--- trunk/fsck.ocfs2/Makefile 2004-09-21 21:05:09 UTC (rev 245)
+++ trunk/fsck.ocfs2/Makefile 2004-09-21 21:51:06 UTC (rev 246)
@@ -2,21 +2,17 @@
include $(TOPDIR)/Preamble.make
-WARNINGS = -Wall -Wstrict-prototypes -Wno-format -Wmissing-prototypes \
- -Wmissing-declarations
+SBIN_PROGRAMS = fsck.ocfs2
-ifdef OCFS_DEBUG
-OPTS = -g
-endif
-CFLAGS = $(OPTS) -fno-strict-aliasing $(WARNINGS)
+INCLUDES = -Iinclude -I$(TOPDIR)/libocfs2/include
+LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
-SBIN_PROGRAMS = fsck.ocfs2
+CFLAGS := -g -Wall -Wstrict-prototypes -Wno-format -Wmissing-prototypes \
+ -Wmissing-declarations -fno-strict-aliasing
-INCLUDES = -I$(TOPDIR)/libocfs2/include
+DEFINES = -DOCFS2_FLAT_INCLUDES
-OPTIMIZE = -O2
-
ifeq ($(OCFS_PROCESSOR),x86_64)
CFLAGS += -m64
endif
@@ -26,17 +22,23 @@
DEFINES += -D__ILP32__
endif
-CFLAGS += $(OPTIMIZE)
+CFILES = fsck.c pass1.c
+HFILES = include/pass1.h
-VERSION_FILES = fsck.c
-VERSION_SRC = fsck.c
+OBJS = $(subst .c,.o,$(CFILES))
+
+VERSION_FILES = $(CFILES) $(HFILES)
+VERSION_SRC = $(CFILES)
VERSION_PREFIX = OCFS2
-#MANS = fsck.ocfs2.8
+DIST_FILES = $(CFILES) $(HFILES)
-DIST_FILES = $(VERSION_FILES) $(VERSION_SRC) #mkfs.ocfs2.8.in
+DIST_RULES = dist-subdircreate
-fsck.ocfs2: fsck.o
- $(LINK)
+dist-subdircreate:
+ $(TOPDIR)/mkinstalldirs $(DIST_DIR)/include
+fsck.ocfs2: $(OBJS)
+ $(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
+
include $(TOPDIR)/Postamble.make
Added: trunk/fsck.ocfs2/fsck.c
===================================================================
--- trunk/fsck.ocfs2/fsck.c 2004-09-21 21:05:09 UTC (rev 245)
+++ trunk/fsck.ocfs2/fsck.c 2004-09-21 21:51:06 UTC (rev 246)
@@ -0,0 +1,209 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * fsck.c
+ *
+ * file system checker for OCFS2
+ *
+ * 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 <getopt.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "ocfs2.h"
+
+#include "fsck.h"
+#include "pass1.h"
+
+static void print_usage(void)
+{
+ fprintf(stderr,
+ "Usage: fsck.ocfs2 [-s <superblock>] [-B <blksize>]\n"
+ " <filename>\n");
+}
+
+static uint64_t read_number(const char *num)
+{
+ uint64_t val;
+ char *ptr;
+
+ val = strtoull(num, &ptr, 0);
+ if (!ptr || *ptr)
+ return 0;
+
+ return val;
+}
+
+extern int opterr, optind;
+extern char *optarg;
+
+static errcode_t o2fsck_state_init(ocfs2_filesys *fs, char *whoami,
+ o2fsck_state *ost)
+{
+ errcode_t ret;
+
+ memset(ost, 0, sizeof(*ost));
+
+ ret = ocfs2_block_bitmap_new(fs, "inodes in use",
+ &ost->ost_used_inodes);
+ if (ret) {
+ com_err(whoami, ret, "while allocating used inodes bitmap");
+ return ret;
+ }
+
+ ret = ocfs2_block_bitmap_new(fs, "inodes with bad fields",
+ &ost->ost_bad_inodes);
+ if (ret) {
+ com_err(whoami, ret, "while allocating bad inodes bitmap");
+ return ret;
+ }
+
+ ret = ocfs2_block_bitmap_new(fs, "directory inodes",
+ &ost->ost_dir_inodes);
+ if (ret) {
+ com_err(whoami, ret, "while allocating dir inodes bitmap");
+ return ret;
+ }
+
+ ret = ocfs2_block_bitmap_new(fs, "regular file inodes",
+ &ost->ost_reg_inodes);
+ if (ret) {
+ com_err(whoami, ret, "while allocating reg inodes bitmap");
+ return ret;
+ }
+
+ ret = ocfs2_block_bitmap_new(fs, "blocks off inodes",
+ &ost->ost_found_blocks);
+ if (ret) {
+ com_err(whoami, ret, "while allocating found blocks bitmap");
+ return ret;
+ }
+
+ ret = ocfs2_block_bitmap_new(fs, "duplicate blocks",
+ &ost->ost_dup_blocks);
+ if (ret) {
+ com_err(whoami, ret, "while allocating duplicate block bitmap");
+ return ret;
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ char *filename;
+ ocfs2_filesys *fs;
+ int64_t blkno, blksize;
+ o2fsck_state ost;
+ int c, ret;
+
+
+ /* These mean "autodetect" */
+ blksize = 0;
+ blkno = 0;
+
+ initialize_ocfs_error_table();
+
+ while((c = getopt(argc, argv, "s:B:")) != EOF) {
+ switch (c) {
+ case 's':
+ blkno = read_number(optarg);
+ if (blkno < OCFS2_SUPER_BLOCK_BLKNO) {
+ fprintf(stderr,
+ "Invalid blkno: %s\n",
+ optarg);
+ print_usage();
+ return 1;
+ }
+ break;
+
+ case 'B':
+ blksize = read_number(optarg);
+ if (blksize < OCFS2_MIN_BLOCKSIZE) {
+ fprintf(stderr,
+ "Invalid blksize: %s\n",
+ optarg);
+ print_usage();
+ return 1;
+ }
+ break;
+
+ default:
+ print_usage();
+ return 1;
+ break;
+ }
+ }
+
+ if (blksize % OCFS2_MIN_BLOCKSIZE) {
+ fprintf(stderr, "Invalid blocksize: %lld\n", blksize);
+ print_usage();
+ return 1;
+ }
+
+ if (optind >= argc) {
+ fprintf(stderr, "Missing filename\n");
+ print_usage();
+ return 1;
+ }
+
+ filename = argv[optind];
+
+ /* XXX we'll decide on a policy for using o_direct in the future.
+ * for now we want to test against loopback files in ext3, say. */
+ ret = ocfs2_open(filename, OCFS2_FLAG_RO | OCFS2_FLAG_BUFFERED, blkno,
+ blksize, &fs);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while opening file \"%s\"", filename);
+ goto out;
+ }
+
+ if (o2fsck_state_init(fs, argv[0], &ost)) {
+ fprintf(stderr, "error allocating run-time state, exiting..\n");
+ return 1;
+ }
+
+ fprintf(stdout, "OCFS2 filesystem on \"%s\":\n", filename);
+ fprintf(stdout,
+ "\tblocksize = %d\n"
+ "\tclustersize = %d\n"
+ "\tclusters = %u\n"
+ "\tblocks = %llu\n",
+ fs->fs_blocksize,
+ fs->fs_clustersize,
+ fs->fs_clusters,
+ fs->fs_blocks);
+
+ ret = o2fsck_pass1(fs, &ost);
+ if (ret)
+ com_err(argv[0], ret, "pass1 failed");
+
+ ret = ocfs2_close(fs);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while closing file \"%s\"", filename);
+ }
+
+out:
+ return 0;
+}
Added: trunk/fsck.ocfs2/include/fsck.h
===================================================================
--- trunk/fsck.ocfs2/include/fsck.h 2004-09-21 21:05:09 UTC (rev 245)
+++ trunk/fsck.ocfs2/include/fsck.h 2004-09-21 21:51:06 UTC (rev 246)
@@ -0,0 +1,38 @@
+/*
+ * fsck.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_FSCK_H__
+#define __O2FSCK_FSCK_H__
+
+typedef struct _o2fsck_state {
+ ocfs2_bitmap *ost_used_inodes;
+ ocfs2_bitmap *ost_bad_inodes;
+ ocfs2_bitmap *ost_dir_inodes;
+ ocfs2_bitmap *ost_reg_inodes;
+
+ ocfs2_bitmap *ost_found_blocks;
+ ocfs2_bitmap *ost_dup_blocks;
+} o2fsck_state;
+
+#endif /* __O2FSCK_FSCK_H__ */
+
Added: trunk/fsck.ocfs2/include/pass1.h
===================================================================
--- trunk/fsck.ocfs2/include/pass1.h 2004-09-21 21:05:09 UTC (rev 245)
+++ trunk/fsck.ocfs2/include/pass1.h 2004-09-21 21:51:06 UTC (rev 246)
@@ -0,0 +1,30 @@
+/*
+ * pass1.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_PASS1_H__
+#define __O2FSCK_PASS1_H__
+
+errcode_t o2fsck_pass1(ocfs2_filesys *fs, o2fsck_state *ost);
+
+#endif /* __O2FSCK_PASS1_H__ */
+
Added: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c 2004-09-21 21:05:09 UTC (rev 245)
+++ trunk/fsck.ocfs2/pass1.c 2004-09-21 21:51:06 UTC (rev 246)
@@ -0,0 +1,209 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * pass1.c
+ *
+ * file system checker for OCFS2
+ *
+ * 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 <string.h>
+
+#include "ocfs2.h"
+
+#include "fsck.h"
+#include "pass1.h"
+
+const char *whoami = "pass1";
+
+/*
+ * for now we're just building up info, we're not actually
+ * writing to disk.
+ *
+ * for each inode:
+ * - verify that i_mode is legal
+ *
+ * We collect the following for future passes:
+ *
+ * - a bitmap of inodes which are in use
+ * - a bitmap of inodes which have bad fields
+ * - a bitmap of data blocks on inodes
+ * - a bitmap of data blocks duplicated between inodes
+ */
+
+static void o2fsck_verify_inode_fields(o2fsck_state *ost, uint64_t blkno,
+ ocfs2_dinode *di)
+{
+ int was_set;
+
+ fprintf(stdout, "inode %llu with size %llu\n",
+ blkno, di->i_size);
+
+ /* do we want to detect and delete corrupt system dir/files here
+ * so we can recreate them later ? */
+
+ /* also make sure the journal inode is ok? */
+
+ /* clamp inodes to > OCFS2_SUPER_BLOCK_BLKNO && < fs->fs_blocks? */
+
+ /* what's our deletion story? i_links_count, dtime, etc.. */
+
+ /* XXX it seems these are expected sometimes? */
+ if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
+ strlen(OCFS2_INODE_SIGNATURE))) {
+ printf("inode %llu has invalid signature\n", blkno);
+ goto bad;
+ }
+ if (!(di->i_flags & OCFS2_VALID_FL)) {
+ printf("inode %llu missing valid flag\n", blkno);
+ goto bad;
+ }
+
+ ocfs2_bitmap_set(ost->ost_used_inodes, blkno, &was_set);
+ if (was_set) {
+ fprintf(stderr, "duplicate inode %llu?\n", blkno);
+ goto bad;
+ }
+
+ if (S_ISDIR(di->i_mode)) {
+ /* XXX record dir for dir block walk */
+ ocfs2_bitmap_set(ost->ost_dir_inodes, blkno, NULL);
+ } else if (S_ISREG(di->i_mode)) {
+ ocfs2_bitmap_set(ost->ost_reg_inodes, blkno, NULL);
+ } else if (S_ISLNK(di->i_mode)) {
+ /* make sure fast symlinks are ok, etc */
+ } else {
+ if (!S_ISCHR(di->i_mode) && !S_ISBLK(di->i_mode) &&
+ !S_ISFIFO(di->i_mode) && !S_ISSOCK(di->i_mode))
+ goto bad;
+
+ /* i_size? what other sanity testing for devices? */
+ }
+
+ return;
+bad:
+ ocfs2_bitmap_set(ost->ost_bad_inodes, blkno, NULL);
+}
+
+struct verifying_blocks {
+ unsigned vb_mark_dir_blocks;
+ uint64_t vb_blocks;
+ o2fsck_state *vb_ost;
+ ocfs2_dinode *vb_di;
+};
+
+static int verify_block(ocfs2_filesys *fs,
+ uint64_t blkno,
+ uint64_t bcount,
+ void *priv_data)
+{
+ struct verifying_blocks *vb = priv_data;
+ ocfs2_dinode *di = vb->vb_di;
+ int was_set;
+
+ ocfs2_bitmap_set(vb->vb_ost->ost_found_blocks, blkno, &was_set);
+ if (was_set) {
+ fprintf(stderr, "duplicate block %llu?\n", blkno);
+ ocfs2_bitmap_set(vb->vb_ost->ost_dup_blocks, blkno, NULL);
+ }
+
+ if (S_ISDIR(di->i_mode)) {
+ /* do we want libocfs2 to record directory blocks or should
+ * we? */
+ }
+
+ vb->vb_blocks++;
+ return 0;
+}
+
+static errcode_t o2fsck_verify_inode_data(ocfs2_filesys *fs, o2fsck_state *ost,
+ uint64_t blkno, ocfs2_dinode *di)
+{
+ struct verifying_blocks vb = {0, };
+ errcode_t ret;
+
+ vb.vb_ost = ost;
+ vb.vb_di = di;
+
+ ret = ocfs2_block_iterate(fs, blkno, 0, verify_block, &vb);
+ if (ret) {
+ com_err(whoami, ret, "walking data blocks");
+ goto out;
+ }
+
+#if 0 /* hmm. */
+ if (vb.vb_blocks != di->i_blocks) {
+ fprintf(stderr, "inode %llu claimed %llu blocks, found"
+ " %llu blocks.\n", di->i_ino, di->i_blocks,
+ vb.vb_blocks);
+ }
+#endif
+
+out:
+ return ret;
+}
+
+errcode_t o2fsck_pass1(ocfs2_filesys *fs, o2fsck_state *ost)
+{
+ errcode_t ret;
+ uint64_t blkno;
+ char *buf;
+ ocfs2_dinode *di;
+ ocfs2_inode_scan *scan;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
+ if (ret) {
+ com_err(whoami, ret,
+ "while allocating inode buffer");
+ goto out;
+ }
+
+ di = (ocfs2_dinode *)buf;
+
+ ret = ocfs2_open_inode_scan(fs, &scan);
+ if (ret) {
+ com_err(whoami, ret,
+ "while opening inode scan");
+ goto out_free;
+ }
+
+ for(;;) {
+ ret = ocfs2_get_next_inode(scan, &blkno, buf);
+ if (ret) {
+ com_err(whoami, ret,
+ "while getting next inode");
+ goto out_close_scan;
+ }
+ if (blkno == 0)
+ break;
+
+ o2fsck_verify_inode_fields(ost, blkno, di);
+ /* XXX be able to mark the blocks in the inode as
+ * bad if the inode was bad */
+ o2fsck_verify_inode_data(fs, ost, blkno, di);
+ }
+
+out_close_scan:
+ ocfs2_close_inode_scan(scan);
+out_free:
+ ocfs2_free(&buf);
+
+out:
+ return 0;
+}
More information about the Ocfs2-tools-commits
mailing list