[Ocfs2-tools-commits] smushran commits r450 - in trunk: . fswrk fswrk/include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Dec 2 17:01:14 CST 2004


Author: smushran
Date: 2004-12-02 17:01:12 -0600 (Thu, 02 Dec 2004)
New Revision: 450

Added:
   trunk/fswrk/
   trunk/fswrk/Cscope.make
   trunk/fswrk/Makefile
   trunk/fswrk/include/
   trunk/fswrk/include/main.h
   trunk/fswrk/include/readfs.h
   trunk/fswrk/include/utils.h
   trunk/fswrk/main.c
   trunk/fswrk/readfs.c
   trunk/fswrk/utils.c
Log:
fswrk shell


Property changes on: trunk/fswrk
___________________________________________________________________
Name: svn:ignore
   + cscope.*
fswrk


Added: trunk/fswrk/Cscope.make
===================================================================
--- trunk/fswrk/Cscope.make	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/Cscope.make	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,10 @@
+.PHONY: cscope
+cscope:
+	rm -f cscope.*
+	echo "-k" >> cscope.files
+	echo "-I inc" >> cscope.files
+	find . -maxdepth 2 -name '*.c' -print >>cscope.files
+	find . -maxdepth 2 -name '*.h' -print >>cscope.files
+	find ../libocfs2/ -maxdepth 2 -name '*.h' -print >>cscope.files
+	find ../libocfs2/ -maxdepth 2 -name '*.c' -print >>cscope.files
+	cscope -b

Added: trunk/fswrk/Makefile
===================================================================
--- trunk/fswrk/Makefile	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/Makefile	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,31 @@
+TOPDIR = ..
+
+include $(TOPDIR)/Preamble.make
+
+SBIN_PROGRAMS = fswrk
+
+DEFINES = -DG_DISABLE_DEPRECATED -DLINUX
+DEFINES += -DVERSION=\"$(VERSION)\"
+
+INCLUDES = -Iinclude -I$(TOPDIR)/libocfs2/include
+INCLUDES += $(GLIB_CFLAGS)
+
+ifdef OCFS_DEBUG
+CFLAGS = -Wall -O -ggdb
+else
+CFLAGS = -Wall -O2
+endif
+
+CFILES = main.c readfs.c utils.c
+
+HFILES = 			\
+	include/main.h		\
+	include/readfs.h	\
+	include/utils.h
+
+OBJS = $(subst .c,.o,$(CFILES))
+
+fswrk: $(OBJS)
+	$(LINK) $(GLIB_LIBS) $(LIBOCFS2_LIBS)
+
+include $(TOPDIR)/Postamble.make

Added: trunk/fswrk/include/main.h
===================================================================
--- trunk/fswrk/include/main.h	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/include/main.h	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,103 @@
+/*
+ * main.h
+ *
+ * Function prototypes, macros, etc. for related 'C' files
+ *
+ * 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 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.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <sys/raw.h>
+#include <linux/kdev_t.h>
+#include <inttypes.h>
+
+#include <glib.h>
+
+#include <linux/types.h>
+
+#include "ocfs2_fs.h"
+#include "ocfs2_disk_dlm.h"
+#include "ocfs1_fs_compat.h"
+
+typedef struct _fswrk_ctxt {
+	char *device;
+	int fd;
+	uint64_t sys_global_inode;
+	uint64_t sys_dlm;
+	uint64_t sys_global_bitmap;
+	uint64_t sys_orphan;
+	uint64_t sys_extent[256];
+	uint64_t sys_inode[256];
+	uint64_t sys_journal[256];
+	uint64_t sys_local[256];
+	uint64_t max_clusters;
+	uint64_t max_blocks;
+	ocfs2_dinode *super_block;
+	ocfs2_dinode *root_dir;
+	ocfs2_dinode *system_dir;
+} fswrk_ctxt;
+
+void *memalign(size_t boundary, size_t size);
+
+#define safefree(_p)	do {if (_p) { free(_p); (_p) = NULL; } } while (0)
+
+#define FSWRK_FATAL(fmt, arg...)	({ fprintf(stderr, "ERROR at %s, %d: " fmt ".  EXITING!!!\n", \
+						   __FILE__, __LINE__, ##arg);  \
+					   raise (SIGTERM);	\
+					   exit(1); \
+					 })
+
+#define FSWRK_FATAL_STR(str)		DBGFS_FATAL(str, "")
+
+#define FSWRK_WARN(fmt, arg...)		fprintf(stderr, "WARNING at %s, %d: " fmt ".\n", \
+						__FILE__, __LINE__, ##arg)
+
+#define FSWRK_WARN_STR(str)		DBGFS_WARN(str, "")
+
+#undef max
+#define max(a,b)	((a) > (b) ? (a) : (b))
+#undef min
+#define min(a,b)	((a) < (b) ? (a) : (b))
+
+/* remaining headers */
+#include <readfs.h>
+#include <utils.h>
+
+#endif		/* __MAIN_H__ */

Added: trunk/fswrk/include/readfs.h
===================================================================
--- trunk/fswrk/include/readfs.h	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/include/readfs.h	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,40 @@
+/*
+ * readfs.h
+ *
+ * Function prototypes, macros, etc. for related 'C' files
+ *
+ * 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 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.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#ifndef __READFS_H__
+#define __READFS_H__
+
+fswrk_ctxt *open_fs(char *device);
+void close_fs(fswrk_ctxt *ctxt);
+int read_super_block (fswrk_ctxt *ctxt);
+int read_inode (fswrk_ctxt *ctxt, __u64 blknum, char *buf);
+int read_group (fswrk_ctxt *ctxt, __u64 blknum, char *buf);
+int traverse_extents (fswrk_ctxt *ctxt, ocfs2_extent_list *ext, GArray *arr);
+void read_dir_block (struct ocfs2_dir_entry *dir, int len, GArray *arr);
+void read_dir (fswrk_ctxt *ctxt, ocfs2_extent_list *ext, __u64 size, GArray *dirarr);
+void read_sysdir (fswrk_ctxt *ctxt);
+int read_file (fswrk_ctxt *ctxt, __u64 blknum, int fdo, char **buf);
+
+#endif		/* __READFS_H__ */

Added: trunk/fswrk/include/utils.h
===================================================================
--- trunk/fswrk/include/utils.h	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/include/utils.h	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,32 @@
+/*
+ * utils.h
+ *
+ * Function prototypes, macros, etc. for related 'C' files
+ *
+ * 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 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.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+void add_extent_rec (GArray *arr, ocfs2_extent_rec *rec);
+void add_dir_rec (GArray *arr, struct ocfs2_dir_entry *rec);
+
+#endif		/* __UTILS_H__ */

Added: trunk/fswrk/main.c
===================================================================
--- trunk/fswrk/main.c	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/main.c	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,164 @@
+/*
+ * main.c
+ *
+ * entry point for fswrk
+ *
+ * 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 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.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#include <main.h>
+
+#define MAX_CORRUPT		1
+
+char *progname = NULL;
+char *device = NULL;
+int corrupt[MAX_CORRUPT];
+
+/*
+ * usage()
+ *
+ */
+static void usage (char *progname)
+{
+	g_print ("Usage: %s [OPTION]... [DEVICE]\n", progname);
+	exit (0);
+}					/* usage */
+
+/*
+ * print_version()
+ *
+ */
+static void print_version (char *progname)
+{
+	fprintf(stderr, "%s %s\n", progname, VERSION);
+}					/* print_version */
+
+
+/*
+ * handle_signal()
+ *
+ */
+static void handle_signal (int sig)
+{
+	switch (sig) {
+	case SIGTERM:
+	case SIGINT:
+		exit(1);
+	}
+
+	return ;
+}					/* handle_signal */
+
+
+/*
+ * read_options()
+ *
+ */
+static int read_options(int argc, char **argv)
+{
+	int c;
+	int ind;
+
+	progname = basename(argv[0]);
+
+	if (argc < 2) {
+		usage(progname);
+		return 1;
+	}
+
+	while(1) {
+		c = getopt(argc, argv, "c:");
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'c':	/* corrupt */
+			ind = strtoul(optarg, NULL, 0);
+			if (ind < MAX_CORRUPT)
+				corrupt[ind] = 1;
+			else {
+				printf("booo\n");
+				return -1;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (optind < argc && argv[optind])
+		device = argv[optind];
+
+	return 0;
+}
+
+/*
+ * main()
+ *
+ */
+int main (int argc, char **argv)
+{
+	fswrk_ctxt *ctxt = NULL;
+	ocfs2_super_block *sb;
+	int i;
+
+#define INSTALL_SIGNAL(sig)					\
+	do {							\
+		if (signal(sig, handle_signal) == SIG_ERR) {	\
+		    printf("Could not set " #sig "\n");		\
+		    goto bail;					\
+		}						\
+	} while (0)
+
+	INSTALL_SIGNAL(SIGTERM);
+	INSTALL_SIGNAL(SIGINT);
+
+	memset(corrupt, 0, sizeof(corrupt));
+
+	if (read_options(argc, argv))
+		goto bail;
+
+	if (!device) {
+		usage(progname);
+		goto bail;
+	}
+
+	print_version (progname);
+
+	ctxt = open_fs(device);
+
+	printf("inode=%llu, dlm=%llu, bm=%llu, orphan=%llu\n",
+	       ctxt->sys_global_inode, ctxt->sys_dlm,
+	       ctxt->sys_global_bitmap, ctxt->sys_orphan);
+
+	sb = &(ctxt->super_block->id2.i_super);
+	for (i = 0; i < sb->s_max_nodes; ++i) {
+		printf("%d. ext=%llu, in=%llu, jrn=%llu, lcl=%llu\n", i,
+		       ctxt->sys_extent[i], ctxt->sys_inode[i],
+		       ctxt->sys_journal[i], ctxt->sys_local[i]);
+	}
+
+bail:
+	if (ctxt)
+		close_fs(ctxt);
+
+	return 0;
+}					/* main */

Added: trunk/fswrk/readfs.c
===================================================================
--- trunk/fswrk/readfs.c	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/readfs.c	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,572 @@
+/*
+ * readfs.c
+ *
+ * reads ocfs2 structures
+ *
+ * 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 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.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#include <main.h>
+
+/*
+ * open_fs()
+ *
+ */
+fswrk_ctxt *open_fs (char *dev)
+{
+	ocfs2_super_block *sb;
+	uint32_t len;
+	fswrk_ctxt *ctxt = NULL;
+
+	if (!dev)
+		return NULL;
+
+	if (!(ctxt = malloc(sizeof(fswrk_ctxt))))
+		FSWRK_FATAL("%s", strerror(errno));
+
+	memset(ctxt, 0, sizeof(fswrk_ctxt));
+
+	ctxt->fd = open (dev, O_DIRECT | O_RDWR);
+	if (ctxt->fd == -1) {
+		printf ("could not open device %s\n", dev);
+		goto bail;
+	}
+
+	ctxt->device = g_strdup (dev);
+
+	if (read_super_block (ctxt) == -1) {
+		close (ctxt->fd);
+		goto bail;
+	}
+
+	sb = &(ctxt->super_block->id2.i_super);
+
+	/* read root inode */
+	len = 1 << sb->s_blocksize_bits;
+	if (!(ctxt->root_dir = memalign(len, len)))
+		FSWRK_FATAL("%s", strerror(errno));
+	if ((pread64(ctxt->fd, (char *)ctxt->root_dir, len,
+		     (sb->s_root_blkno << sb->s_blocksize_bits))) == -1)
+		FSWRK_FATAL("%s", strerror(errno));
+
+	/* read sysdir inode */
+	len = 1 << sb->s_blocksize_bits;
+	if (!(ctxt->system_dir = memalign(len, len)))
+		FSWRK_FATAL("%s", strerror(errno));
+	if ((pread64(ctxt->fd, (char *)ctxt->system_dir, len,
+		     (sb->s_system_dir_blkno << sb->s_blocksize_bits))) == -1)
+		FSWRK_FATAL("%s", strerror(errno));
+
+	/* load sysfiles blknums */
+	read_sysdir(ctxt);
+
+	/* get the max clusters/blocks */
+	ctxt->max_clusters = ctxt->super_block->i_clusters;
+	ctxt->max_blocks = ctxt->max_clusters << (sb->s_clustersize_bits -
+						  sb->s_blocksize_bits);
+
+	return ctxt;
+
+bail:
+	safefree(ctxt);
+	return NULL;
+}					/* open_fs */
+
+/*
+ * close_fs()
+ *
+ */
+void close_fs (fswrk_ctxt *ctxt)
+{
+	if (ctxt->device) {
+		safefree (ctxt->device);
+
+		close (ctxt->fd);
+		ctxt->fd = -1;
+
+		safefree (ctxt->super_block);
+		safefree (ctxt->root_dir);
+		safefree (ctxt->system_dir);
+	} else
+		printf ("device not open\n");
+
+	return ;
+}					/* close_fs */
+
+/*
+ * read_super_block()
+ *
+ */
+int read_super_block (fswrk_ctxt *ctxt)
+{
+	int ret = -1;
+	uint64_t off;
+	ocfs1_vol_disk_hdr *hdr;
+	ocfs2_dinode *di;
+	uint32_t bits = 9;
+	uint32_t buflen;
+	char *buf = NULL;
+
+	for (bits = 9; bits < 13; bits++) {
+		buflen = 1 << bits;
+		if (!(buf = memalign(buflen, buflen)))
+			FSWRK_FATAL("%s", strerror(errno));
+
+		if ((ret =  pread64(ctxt->fd, buf, buflen, 0)) == -1) {
+			safefree (buf);
+			continue;
+		} else
+			break;
+	}
+
+	if (ret == -1)
+		FSWRK_FATAL ("unable to read the first block");
+
+	hdr = (ocfs1_vol_disk_hdr *)buf;
+	if (memcmp(hdr->signature, OCFS1_VOLUME_SIGNATURE,
+		   strlen (OCFS1_VOLUME_SIGNATURE)) == 0) {
+		printf("OCFS1 detected\n");
+		ret = -1;
+		goto bail;
+	}
+
+	/*
+	 * Now check at magic offset for 512, 1024, 2048, 4096
+	 * blocksizes.  4096 is the maximum blocksize because it is
+	 * the minimum clustersize.
+	 */
+	for (; bits < 13; bits++) {
+		if (!buf) {
+			buflen = 1 << bits;
+			if (!(buf = memalign(buflen, buflen)))
+				FSWRK_FATAL("%s", strerror(errno));
+		}
+
+		off = OCFS2_SUPER_BLOCK_BLKNO << bits;
+		if ((pread64(ctxt->fd, buf, buflen, off)) == -1)
+			FSWRK_FATAL("%s", strerror(errno));
+
+		di = (ocfs2_dinode *)buf;
+		if (!memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
+			    strlen(OCFS2_SUPER_BLOCK_SIGNATURE))) {
+			ret = 0;
+			break;
+		}
+		safefree (buf);
+	}
+
+	if (bits >= 13) {
+		printf("Not an OCFS2 volume\n");
+		ret = -1;
+	}
+
+bail:
+	if (!ret)
+		ctxt->super_block = (ocfs2_dinode *)buf;
+	else
+		safefree (buf);
+	
+	return ret;
+}				/* read_super_block */
+
+/*
+ * read_inode()
+ *
+ */
+int read_inode (fswrk_ctxt *ctxt, uint64_t blkno, char *buf)
+{
+	ocfs2_dinode *inode;
+	int ret = 0;
+	ocfs2_super_block *sb = &(ctxt->super_block->id2.i_super);
+	int len = 1 << sb->s_blocksize_bits;
+	uint64_t off = blkno << sb->s_blocksize_bits;
+
+	if ((pread64(ctxt->fd, buf, len, off)) == -1)
+		FSWRK_FATAL("%s off=%"PRIu64, strerror(errno), off);
+
+	inode = (ocfs2_dinode *)buf;
+
+	if (memcmp(inode->i_signature, OCFS2_INODE_SIGNATURE,
+		   sizeof(OCFS2_INODE_SIGNATURE)))
+		ret = -1;
+
+	return ret;
+}				/* read_inode */
+
+/*
+ * read_group()
+ *
+ */
+int read_group (fswrk_ctxt *ctxt, uint64_t blkno, char *buf)
+{
+	ocfs2_group_desc *bg;
+	int ret = 0;
+	ocfs2_super_block *sb = &(ctxt->super_block->id2.i_super);
+	int len = 1 << sb->s_blocksize_bits;
+	uint64_t off = blkno << sb->s_blocksize_bits;
+
+	if ((pread64(ctxt->fd, buf, len, off)) == -1)
+		FSWRK_FATAL("%s off=%"PRIu64, strerror(errno), off);
+
+	bg = (ocfs2_group_desc *)buf;
+
+	if (memcmp(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
+		   sizeof(OCFS2_GROUP_DESC_SIGNATURE)))
+		ret = -1;
+
+	return ret;
+}				/* read_group */
+
+/*
+ * traverse_extents()
+ *
+ */
+int traverse_extents (fswrk_ctxt *ctxt, ocfs2_extent_list *ext, GArray *arr)
+{
+	ocfs2_extent_block *blk;
+	ocfs2_extent_rec *rec;
+	int ret = 0;
+	uint64_t off;
+	char *buf = NULL;
+	uint32_t buflen;
+	int i;
+	ocfs2_super_block *sb = &(ctxt->super_block->id2.i_super);
+
+	for (i = 0; i < ext->l_next_free_rec; ++i) {
+		rec = &(ext->l_recs[i]);
+		if (ext->l_tree_depth == 0)
+			add_extent_rec (arr, rec);
+		else {
+			buflen = 1 << sb->s_blocksize_bits;
+			if (!(buf = memalign(buflen, buflen)))
+				FSWRK_FATAL("%s", strerror(errno));
+
+			off = (uint64_t)rec->e_blkno << sb->s_blocksize_bits;
+			if ((pread64 (ctxt->fd, buf, buflen, off)) == -1)
+				FSWRK_FATAL("%s", strerror(errno));
+
+			blk = (ocfs2_extent_block *)buf;
+
+			traverse_extents (ctxt, &(blk->h_list), arr);
+		}
+	}
+
+	safefree (buf);
+	return ret;
+}				/* traverse_extents */
+
+/*
+ * read_dir_block()
+ *
+ */
+void read_dir_block (struct ocfs2_dir_entry *dir, int len, GArray *arr)
+{
+	char *p;
+	struct ocfs2_dir_entry *rec;
+
+	p = (char *) dir;
+
+	while (p < (((char *)dir) + len)) {
+		rec = (struct ocfs2_dir_entry *)p;
+		if (rec->inode)
+			add_dir_rec (arr, rec);
+		p += rec->rec_len;
+	}
+
+	return ;
+}				/* read_dir_block */
+
+/*
+ * read_dir()
+ *
+ */
+void read_dir (fswrk_ctxt *ctxt, ocfs2_extent_list *ext, uint64_t size, GArray *dirarr)
+{
+	ocfs2_extent_rec *rec;
+	GArray *arr = NULL;
+	unsigned int i = 0;
+	char *buf = NULL;
+	ocfs2_super_block *sb = &(ctxt->super_block->id2.i_super);
+	uint32_t len;
+	uint64_t off;
+	uint64_t foff;
+
+	arr = g_array_new(0, 1, sizeof(ocfs2_extent_rec));
+
+	traverse_extents (ctxt, ext, arr);
+
+	for (i = 0; i < arr->len; ++i) {
+		rec = &(g_array_index(arr, ocfs2_extent_rec, i));
+
+		off = rec->e_blkno << sb->s_blocksize_bits;
+                foff = rec->e_cpos << sb->s_clustersize_bits;
+		len = rec->e_clusters << sb->s_clustersize_bits;
+		if ((foff + len) > size)
+			len = size - foff;
+
+		if (!(buf = memalign((1 << sb->s_blocksize_bits), len)))
+			FSWRK_FATAL("%s", strerror(errno));
+
+		if ((pread64(ctxt->fd, buf, len, off)) == -1)
+			FSWRK_FATAL("%s", strerror(errno));
+
+		read_dir_block ((struct ocfs2_dir_entry *)buf, len, dirarr);
+
+		safefree (buf);
+	}
+
+	if (arr)
+		g_array_free (arr, 1);
+
+	return ;
+}				/* read_dir */
+
+/*
+ * read_sysdir()
+ *
+ */
+void read_sysdir (fswrk_ctxt *ctxt)
+{
+	ocfs2_dinode *di;
+	struct ocfs2_dir_entry *rec;
+	GArray *dirarr = NULL;
+	char *global_inode_file = sysfile_info[GLOBAL_INODE_ALLOC_SYSTEM_INODE].name;
+	char *dlm_file = sysfile_info[DLM_SYSTEM_INODE].name;
+	char *global_bitmap_file = sysfile_info[GLOBAL_BITMAP_SYSTEM_INODE].name;
+	char *orphan_file = sysfile_info[ORPHAN_DIR_SYSTEM_INODE].name;
+	char *extent_file[256];
+	char *inode_file[256];
+	char *journal_file[256];
+	char *local_file[256];
+	ocfs2_super_block *sb = &(ctxt->super_block->id2.i_super);
+	char tmpstr[40];
+	unsigned int i, j;
+
+	di = (ocfs2_dinode *)ctxt->system_dir;
+
+	if (!S_ISDIR(di->i_mode)) {
+		printf("No system directory on the volume\n");
+		goto bail;
+	}
+
+	dirarr = g_array_new(0, 1, sizeof(struct ocfs2_dir_entry));
+
+	read_dir (ctxt, &(di->id2.i_list), di->i_size, dirarr);
+
+	/* generate node specific sysfile names */
+	for (i = 0; i < sb->s_max_nodes; ++i) {
+		/* extent */
+		snprintf (tmpstr, sizeof(tmpstr),
+			  sysfile_info[EXTENT_ALLOC_SYSTEM_INODE].name, i);
+		extent_file[i] = strdup (tmpstr);
+		ctxt->sys_extent[i] = 0;
+
+		/* inode */
+		snprintf (tmpstr, sizeof(tmpstr),
+			  sysfile_info[INODE_ALLOC_SYSTEM_INODE].name, i);
+		inode_file[i] = strdup (tmpstr);
+		ctxt->sys_inode[i] = 0;
+
+		/* journal */
+		snprintf (tmpstr, sizeof(tmpstr),
+			  sysfile_info[JOURNAL_SYSTEM_INODE].name, i);
+		journal_file[i] = strdup (tmpstr);
+		ctxt->sys_journal[i] = 0;
+
+		/* local */
+		snprintf (tmpstr, sizeof(tmpstr),
+			  sysfile_info[LOCAL_ALLOC_SYSTEM_INODE].name, i);
+		local_file[i] = strdup (tmpstr);
+		ctxt->sys_local[i] = 0;
+	}
+
+	/* fill blknos for system files */
+	for (i = 0; i < dirarr->len; ++i) {
+		rec = &(g_array_index(dirarr, struct ocfs2_dir_entry, i));
+
+		/* global inode */
+		if (!ctxt->sys_global_inode &&
+		    !strncmp (rec->name, global_inode_file, strlen(global_inode_file))) {
+			ctxt->sys_global_inode = rec->inode;
+			continue;
+		}
+
+		/* dlm */
+		if (!ctxt->sys_dlm &&
+		    !strncmp (rec->name, dlm_file, strlen(dlm_file))) {
+			ctxt->sys_dlm = rec->inode;
+			continue;
+		}
+
+		/* global bitmap */
+		if (!ctxt->sys_global_bitmap &&
+		    !strncmp (rec->name, global_bitmap_file, strlen(global_bitmap_file))) {
+			ctxt->sys_global_bitmap = rec->inode;
+			continue;
+		}
+
+		/* orphan */
+		if (!ctxt->sys_orphan &&
+		    !strncmp (rec->name, orphan_file, strlen(orphan_file))) {
+			ctxt->sys_orphan = rec->inode;
+			continue;
+		}
+
+		for (j = 0; j < sb->s_max_nodes; ++j) {
+			/* extent alloc */
+			if (!ctxt->sys_extent[j] &&
+			    !strncmp (rec->name, extent_file[j], strlen(extent_file[j]))) {
+				ctxt->sys_extent[j] = rec->inode;
+				break;
+			}
+
+			/* inode alloc */
+			if (!ctxt->sys_inode[j] &&
+			    !strncmp (rec->name, inode_file[j], strlen(inode_file[j]))) {
+				ctxt->sys_inode[j] = rec->inode;
+				break;
+			}
+
+			/* journal */
+			if (!ctxt->sys_journal[j] &&
+			    !strncmp (rec->name, journal_file[j], strlen(journal_file[j]))) {
+				ctxt->sys_journal[j] = rec->inode;
+				break;
+			}
+
+			/* local alloc */
+			if (!ctxt->sys_local[j] &&
+			    !strncmp (rec->name, local_file[j], strlen(local_file[j]))) {
+				ctxt->sys_local[j] = rec->inode;
+				break;
+			}
+		}
+	}
+
+bail:
+	if (dirarr)
+		g_array_free (dirarr, 1);
+
+	for (i = 0; i < sb->s_max_nodes; ++i) {
+		safefree (extent_file[i]);
+		safefree (inode_file[i]);
+		safefree (journal_file[i]);
+		safefree (local_file[i]);
+	}
+
+	return ;
+}				/* read_sysdir */
+
+#if 0
+/*
+ * read_file()
+ *
+ */
+int read_file (int fd, uint64_t blknum, int fdo, char **buf)
+{
+	ocfs2_dinode *inode = NULL;
+	GArray *arr = NULL;
+	ocfs2_extent_rec *rec;
+	char *p = NULL;
+	uint64_t off, foff, len;
+	unsigned int i;
+	char *newbuf = NULL;
+	uint64_t newlen = 0;
+	char *inode_buf = NULL;
+	uint64_t buflen = 0;
+	uint64_t rndup = 0;
+	int ret = -1;
+
+	arr = g_array_new(0, 1, sizeof(ocfs2_extent_rec));
+
+	buflen = 1 << gbls.blocksize_bits;
+	if (!(inode_buf = memalign(buflen, buflen)))
+		FSWRK_FATAL("%s", strerror(errno));
+
+	if ((read_inode (fd, blknum, inode_buf, buflen)) == -1) {
+		printf("Not an inode\n");
+		goto bail;
+	}
+	inode = (ocfs2_dinode *)inode_buf;
+
+	traverse_extents (fd, &(inode->id2.i_list), arr, 0, stdout);
+
+	if (fdo == -1) {
+		newlen = inode->i_size;
+	} else {
+		newlen = 1024 * 1024;
+		if (fdo > 2) {
+			fchmod (fdo, inode->i_mode);
+			fchown (fdo, inode->i_uid, inode->i_gid);
+		}
+	}
+
+	if (!(newbuf = memalign((1 << gbls.blocksize_bits), newlen)))
+		FSWRK_FATAL("%s", strerror(errno));
+
+	p = newbuf;
+
+	for (i = 0; i < arr->len; ++i) {
+		rec = &(g_array_index(arr, ocfs2_extent_rec, i));
+		off = rec->e_blkno << gbls.blocksize_bits;
+		foff = rec->e_cpos << gbls.clustersize_bits;
+		len = rec->e_clusters << gbls.clustersize_bits;
+		if ((foff + len) > inode->i_size)
+			len = inode->i_size - foff;
+
+		while (len) {
+			buflen = min (newlen, len);
+			/* rndup is reqd because source is read o_direct */
+			rndup = buflen % (1 << gbls.blocksize_bits);
+			rndup = (rndup ? (1 << gbls.blocksize_bits) - rndup : 0);
+			buflen += rndup;
+
+			if ((pread64(fd, p, buflen, off)) == -1)
+				FSWRK_FATAL("%s", strerror(errno));
+
+			buflen -= rndup;
+
+			if (fdo != -1) {
+				if (!(write (fdo, p, buflen)))
+					FSWRK_FATAL("%s", strerror(errno));
+			} else
+				p += buflen;
+			len -= buflen;
+			off += buflen;
+		}
+	}
+
+	ret = 0;
+	if (buf) {
+		*buf = newbuf;
+		ret = newlen;
+	}
+
+bail:
+	safefree (inode_buf);
+	if (ret == -1 || !buf)
+		safefree (newbuf);
+
+	if (arr)
+		g_array_free (arr, 1);
+
+	return ret;
+}				/* read_file */
+#endif

Added: trunk/fswrk/utils.c
===================================================================
--- trunk/fswrk/utils.c	2004-12-02 22:45:14 UTC (rev 449)
+++ trunk/fswrk/utils.c	2004-12-02 23:01:12 UTC (rev 450)
@@ -0,0 +1,74 @@
+/*
+ * utils.c
+ *
+ * utility functions
+ *
+ * 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 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.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#include <main.h>
+
+/*
+ * add_extent_rec()
+ *
+ */
+void add_extent_rec (GArray *arr, ocfs2_extent_rec *rec)
+{
+	ocfs2_extent_rec *new;
+
+	if (!arr)
+		return ;
+
+	if (!(new = malloc(sizeof(ocfs2_extent_rec))))
+		FSWRK_FATAL("%s", strerror(errno));
+
+	memcpy(new, rec, sizeof(ocfs2_extent_rec));
+	g_array_append_vals(arr, new, 1);
+
+	return ;
+}				/* add_extent_rec */
+
+/*
+ * add_dir_rec()
+ *
+ */
+void add_dir_rec (GArray *arr, struct ocfs2_dir_entry *rec)
+{
+	struct ocfs2_dir_entry *new;
+
+	if (!arr)
+		return ;
+
+	if (!(new = malloc(sizeof(struct ocfs2_dir_entry))))
+		FSWRK_FATAL("%s", strerror(errno));
+
+	memset(new, 0, sizeof(struct ocfs2_dir_entry));
+
+	new->inode = rec->inode;
+	new->rec_len = rec->rec_len;
+	new->name_len = rec->name_len;
+	new->file_type = rec->file_type;
+	strncpy(new->name, rec->name, rec->name_len);
+	new->name[rec->name_len] = '\0';
+
+	g_array_append_vals(arr, new, 1);
+
+	return ;
+}				/* add_dir_rec */



More information about the Ocfs2-tools-commits mailing list