[Ocfs2-tools-commits] jlbec commits r309 - in trunk: debugfs.ocfs2 debugfs.ocfs2/include extras libocfs2 libocfs2/include mkfs.ocfs2 mounted.ocfs2 ocfs2cdsl

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Fri Oct 1 20:22:55 CDT 2004


Author: jlbec
Date: 2004-10-01 20:22:53 -0500 (Fri, 01 Oct 2004)
New Revision: 309

Added:
   trunk/extras/set_random_bits.c
   trunk/libocfs2/chain.c
Modified:
   trunk/debugfs.ocfs2/Makefile
   trunk/debugfs.ocfs2/commands.c
   trunk/debugfs.ocfs2/dump.c
   trunk/debugfs.ocfs2/include/dump.h
   trunk/debugfs.ocfs2/include/readfs.h
   trunk/debugfs.ocfs2/readfs.c
   trunk/extras/
   trunk/extras/Makefile
   trunk/libocfs2/Makefile
   trunk/libocfs2/bitmap.c
   trunk/libocfs2/extent_map.c
   trunk/libocfs2/extents.c
   trunk/libocfs2/include/bitmap.h
   trunk/libocfs2/include/ocfs2.h
   trunk/libocfs2/include/ocfs2_fs.h
   trunk/libocfs2/inode_scan.c
   trunk/libocfs2/ocfs2_err.et.in
   trunk/mkfs.ocfs2/Makefile
   trunk/mkfs.ocfs2/mkfs.c
   trunk/mounted.ocfs2/Makefile
   trunk/ocfs2cdsl/Makefile
   trunk/ocfs2cdsl/ocfs2cdsl.c
Log:

o Merge the dlm_changes branch (which didn't change the DLM so much)
  into trunk.  This actually CHANGES the DISK a LOT.  The new chain
  allocators have landed.



Modified: trunk/debugfs.ocfs2/Makefile
===================================================================
--- trunk/debugfs.ocfs2/Makefile	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/debugfs.ocfs2/Makefile	2004-10-02 01:22:53 UTC (rev 309)
@@ -12,16 +12,20 @@
 CFLAGS += -Wall -O2
 
 CFILES = main.c commands.c dump.c readfs.c utils.c journal.c bindraw.c
-HFILES = include/main.h include/commands.h include/dump.h include/readfs.h include/utils.h include/jbd.h include/journal.h include/bindraw.h
+HFILES =			\
+	include/main.h		\
+	include/commands.h	\
+	include/dump.h		\
+	include/readfs.h	\
+	include/utils.h		\
+	include/jbd.h		\
+	include/journal.h	\
+	include/bindraw.h
 
 OBJS = $(subst .c,.o,$(CFILES))
 
 LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
 
-VERSION_FILES = $(CFILES) $(HFILES)
-VERSION_SRC = $(CFILES)
-VERSION_PREFIX = OCFS2
-
 MANS = debugfs.ocfs2.8
 
 DIST_FILES = $(CFILES) $(HFILES) README debugfs.ocfs2.8.in

Modified: trunk/debugfs.ocfs2/commands.c
===================================================================
--- trunk/debugfs.ocfs2/commands.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/debugfs.ocfs2/commands.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -61,6 +61,8 @@
 static void do_publish (char **args);
 static void do_vote (char **args);
 static void do_journal (char **args);
+static void do_group (char **args);
+static void do_header (char **args);
 
 extern gboolean allow_write;
 extern gboolean no_raw_bind;
@@ -118,8 +120,10 @@
   { "publish", do_publish },
   { "vote", do_vote },
 
-  { "logdump", do_journal }
+  { "logdump", do_journal },
 
+  { "group", do_group },
+  { "header", do_header }
 };
 
 
@@ -526,6 +530,8 @@
 
 	if ((inode->i_flags & OCFS2_LOCAL_ALLOC_FL))
 		dump_local_alloc(out, &(inode->id2.i_lab));
+	else if ((inode->i_flags & OCFS2_CHAIN_FL))
+		dump_chain_list(out, &(inode->id2.i_chain));
 	else
 		traverse_extents(gbls.dev_fd, &(inode->id2.i_list), NULL, 1, out);
 
@@ -706,8 +712,114 @@
 	return ;
 }					/* do_journal */
 
+/*
+ * do_group()
+ *
+ */
+static void do_group (char **args)
+{
+	char *opts = args[1];
+	ocfs2_group_desc *bg;
+	__u32 blknum;
+	char *buf = NULL;
+	__u32 buflen;
+	FILE *out;
 
+	if (gbls.dev_fd == -1) {
+		printf ("device not open\n");
+		goto bail;
+	}
+
+	buflen = 1 << gbls.blksz_bits;
+	if (!(buf = memalign(buflen, buflen)))
+		DBGFS_FATAL("%s", strerror(errno));
+
+	if (!opts) {
+		printf("no block number specified\n");
+		goto bail;
+	}
+
+	blknum = atoi(opts);
+	if (blknum > gbls.max_blocks) {
+		printf("block number is too large\n");
+		goto bail;
+	}
+	if ((read_group (gbls.dev_fd, blknum, buf, buflen)) == -1) {
+		printf("Not a group descriptor\n");
+		goto bail;
+	}
+	bg = (ocfs2_group_desc *)buf;
+
+	out = open_pager();
+	dump_group_descriptor(out, bg);
+
+	close_pager (out);
+
+bail:
+	safefree (buf);
+	return ;
+}					/* do_group */
+
 /*
+ * do_header()
+ *
+ */
+static void do_header (char **args)
+{
+	char *opts = args[1];
+	ocfs2_extent_block *eb;
+	__u32 blknum;
+	char *buf = NULL;
+	__u32 buflen;
+	FILE *out;
+	__u64 off;
+
+	if (gbls.dev_fd == -1) {
+		printf ("device not open\n");
+		goto bail;
+	}
+
+	buflen = 1 << gbls.blksz_bits;
+	if (!(buf = memalign(buflen, buflen)))
+		DBGFS_FATAL("%s", strerror(errno));
+
+	if (!opts) {
+		printf("no block number specified\n");
+		goto bail;
+	}
+
+	blknum = atoi(opts);
+	if (blknum > gbls.max_blocks) {
+		printf("block number is too large\n");
+		goto bail;
+	}
+
+	off = blknum << gbls.blksz_bits;
+	if ((pread64 (gbls.dev_fd, buf, buflen, off)) == -1) {
+		printf("error reading block!\n");
+		goto bail;
+	}
+
+	out = open_pager();
+
+	eb = (ocfs2_extent_block *)buf;
+	if (memcmp(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
+		   sizeof(OCFS2_EXTENT_BLOCK_SIGNATURE))) {
+		printf("Not an extent block\n");
+		goto bail;
+	}
+
+	dump_extent_block(out, eb);
+	dump_extent_list(out, &eb->h_list);
+
+	close_pager (out);
+
+bail:
+	safefree (buf);
+	return ;
+}					/* do_header */
+
+/*
  * handle_signal()
  *
  */

Modified: trunk/debugfs.ocfs2/dump.c
===================================================================
--- trunk/debugfs.ocfs2/dump.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/debugfs.ocfs2/dump.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -135,6 +135,8 @@
 		g_string_append (flags, "journal ");
 	if (in->i_flags & OCFS2_DLM_FL)
 		g_string_append (flags, "dlm ");
+	if (in->i_flags & OCFS2_CHAIN_FL)
+		g_string_append (flags, "chain ");
 
 	fprintf(out, "\tInode: %llu   Mode: 0%0o   Generation: %u\n",
 	        (unsigned long long)in->i_blkno, mode, in->i_generation);
@@ -162,8 +164,8 @@
 	fprintf(out, "\tdtime: 0x%llx -- %s", (unsigned long long)in->i_dtime, str);
 
 	fprintf(out, "\tLast Extblk: %llu\n", (unsigned long long)in->i_last_eb_blk);
-	fprintf(out, "\tSub Alloc Node: %u   Sub Alloc Blknum: %llu\n",
-	       in->i_suballoc_node, (unsigned long long)in->i_suballoc_blkno);
+	fprintf(out, "\tSub Alloc Node: %u   Sub Alloc Bit: %u\n",
+	       in->i_suballoc_node, in->i_suballoc_bit);
 
 	if (in->i_flags & OCFS2_BITMAP_FL)
 		fprintf(out, "\tBitmap Total: %u   Used: %u   Clear: %u\n",
@@ -215,6 +217,34 @@
  * dump_extent_list()
  *
  */
+void dump_chain_list (FILE *out, ocfs2_chain_list *cl)
+{
+	ocfs2_chain_rec *rec;
+	int i;
+
+	fprintf(out, "\tClusters Per Group: %u   Bits Per Cluster: %u\n",
+		cl->cl_cpg, cl->cl_bpc);
+
+	fprintf(out, "\tCount: %u   Next Free Record: %u\n",
+		cl->cl_count, cl->cl_next_free_rec);
+
+	if (!cl->cl_next_free_rec)
+		goto bail;
+
+	for (i = 0; i < cl->cl_next_free_rec; ++i) {
+		rec = &(cl->cl_recs[i]);
+		fprintf(out, "\t## Bits Total    Bits Free      Disk Offset\n");
+
+		fprintf(out, "\t%-2d %-11u   %-12u   %llu\n", i, rec->c_total,
+			rec->c_free, (unsigned long long)rec->c_blkno);
+		traverse_chain(out, rec->c_blkno);
+		fprintf(out, "\n");
+	}
+
+bail:
+	return ;
+}				/* dump_chain_list */
+
 void dump_extent_list (FILE *out, ocfs2_extent_list *ext)
 {
 	ocfs2_extent_rec *rec;
@@ -244,8 +274,8 @@
  */
 void dump_extent_block (FILE *out, ocfs2_extent_block *blk)
 {
-	fprintf (out, "\tSubAlloc Blknum: %llu   SubAlloc Node: %u\n",
-		 (unsigned long long)blk->h_suballoc_blkno, blk->h_suballoc_node);
+	fprintf (out, "\tSubAlloc Bit: %u   SubAlloc Node: %u\n",
+		 blk->h_suballoc_bit, blk->h_suballoc_node);
 
 	fprintf (out, "\tBlknum: %llu   Parent: %llu   Next Leaf: %llu\n",
 		 (unsigned long long)blk->h_blkno,
@@ -255,7 +285,58 @@
 	return ;
 }				/* dump_extent_block */
 
+void traverse_chain(FILE *out, __u64 blknum)
+{
+	ocfs2_group_desc *bg;
+	char *buf = NULL;
+	__u32 buflen;
+
+	buflen = 1 << gbls.blksz_bits;
+	if (!(buf = memalign(buflen, buflen)))
+		DBGFS_FATAL("%s", strerror(errno));
+
+	do {
+		if ((read_group (gbls.dev_fd, blknum, buf, buflen)) == -1) {
+			printf("Not a group descriptor\n");
+			goto bail;
+		}
+		bg = (ocfs2_group_desc *)buf;
+		dump_group_descriptor(out, bg);
+		blknum = bg->bg_next_group;
+	} while (blknum);
+	
+bail:
+	safefree (buf);
+	return ;
+}
+
 /*
+ * dump_group_descriptor()
+ *
+ */
+void dump_group_descriptor (FILE *out, ocfs2_group_desc *blk)
+{
+
+	fprintf (out, "\tParent Chain: %u   Blknum: %llu\n",
+		 blk->bg_chain,
+		 blk->bg_blkno);
+
+	fprintf (out, "\tFree Bits Count: %u   Group Bits: %u   "
+		 "Group Size: %u\n",
+		 blk->bg_free_bits_count,
+		 blk->bg_bits,
+		 blk->bg_size);
+
+	fprintf (out, "\tNext Group: %llu   Parent Dinode: %llu  "
+		 "Generation: %u\n",
+		 (unsigned long long)blk->bg_next_group,
+		 (unsigned long long)blk->bg_parent_dinode,
+		 blk->bg_generation);
+
+	return ;
+}				/* dump_group_descriptor */
+
+/*
  * dump_dir_entry()
  *
  */

Modified: trunk/debugfs.ocfs2/include/dump.h
===================================================================
--- trunk/debugfs.ocfs2/include/dump.h	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/debugfs.ocfs2/include/dump.h	2004-10-02 01:22:53 UTC (rev 309)
@@ -31,7 +31,9 @@
 void dump_inode (FILE *out, ocfs2_dinode *in);
 void dump_disk_lock (FILE *out, ocfs2_disk_lock *dl);
 void dump_extent_list (FILE *out, ocfs2_extent_list *ext);
+void dump_chain_list (FILE *out, ocfs2_chain_list *cl);
 void dump_extent_block (FILE *out, ocfs2_extent_block *blk);
+void dump_group_descriptor (FILE *out, ocfs2_group_desc *blk);
 void dump_dir_entry (FILE *out, GArray *arr);
 void dump_config (FILE *out, char *buf);
 void dump_publish (FILE *out, char *buf);
@@ -41,5 +43,5 @@
 void dump_jbd_block (FILE *out, journal_header_t *header, __u64 blknum);
 void dump_jbd_metadata (FILE *out, int type, char *buf, __u64 blknum);
 void dump_jbd_unknown (FILE *out, __u64 start, __u64 end);
-
+void traverse_chain(FILE *out, __u64 blknum);
 #endif		/* __DUMP_H__ */

Modified: trunk/debugfs.ocfs2/include/readfs.h
===================================================================
--- trunk/debugfs.ocfs2/include/readfs.h	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/debugfs.ocfs2/include/readfs.h	2004-10-02 01:22:53 UTC (rev 309)
@@ -28,6 +28,7 @@
 
 int read_super_block (int fd, char **buf);
 int read_inode (int fd, __u64 blknum, char *buf, int buflen);
+int read_group (int fd, __u64 blknum, char *buf, int buflen);
 int traverse_extents (int fd, ocfs2_extent_list *ext, GArray *arr, int dump, FILE *out);
 void read_dir_block (struct ocfs2_dir_entry *dir, int len, GArray *arr);
 void read_dir (int fd, ocfs2_extent_list *ext, __u64 size, GArray *dirarr);

Modified: trunk/debugfs.ocfs2/readfs.c
===================================================================
--- trunk/debugfs.ocfs2/readfs.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/debugfs.ocfs2/readfs.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -124,6 +124,30 @@
 }				/* read_inode */
 
 /*
+ * read_group()
+ *
+ */
+int read_group (int fd, __u64 blknum, char *buf, int buflen)
+{
+	uint64_t off;
+	ocfs2_group_desc *bg;
+	int ret = 0;
+
+	off = blknum << gbls.blksz_bits;
+
+	if ((pread64(fd, buf, buflen, off)) == -1)
+		DBGFS_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()
  *
  */


Property changes on: trunk/extras
___________________________________________________________________
Name: svn:ignore
   - .*.sw?
find_hardlinks
find_dup_extents
find_inode_paths

   + .*.sw?
find_hardlinks
find_dup_extents
find_inode_paths
set_random_bits


Modified: trunk/extras/Makefile
===================================================================
--- trunk/extras/Makefile	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/extras/Makefile	2004-10-02 01:22:53 UTC (rev 309)
@@ -11,7 +11,7 @@
 
 CFLAGS = $(OPTS) -fno-strict-aliasing $(WARNINGS) 
 
-UNINST_PROGRAMS = find_hardlinks find_dup_extents find_inode_paths
+UNINST_PROGRAMS = find_hardlinks find_dup_extents find_inode_paths set_random_bits
 
 INCLUDES = -I../libocfs2/include
 
@@ -33,12 +33,14 @@
 FIND_HARDLINKS_CFILES = find_hardlinks.c
 FIND_DUP_EXTENTS_CFILES = find_dup_extents.c
 FIND_INODE_PATHS_CFILES = find_inode_paths.c
+SET_RANDOM_BITS_CFILES = set_random_bits.c
 
-DIST_FILES = $(FIND_HARDLINKS_CFILES) $(FIND_DUP_EXTENTS_CFILES) $(FIND_INODE_PATHS_CFILES)
+DIST_FILES = $(FIND_HARDLINKS_CFILES) $(FIND_DUP_EXTENTS_CFILES) $(FIND_INODE_PATHS_CFILES) $(SET_RANDOM_BITS_CFILES)
+
 FIND_HARDLINKS_OBJS = $(subst .c,.o,$(FIND_HARDLINKS_CFILES))
 FIND_DUP_EXTENTS_OBJS = $(subst .c,.o,$(FIND_DUP_EXTENTS_CFILES))
 FIND_INODE_PATHS_OBJS = $(subst .c,.o,$(FIND_INODE_PATHS_CFILES))
-
+SET_RANDOM_BITS_OBJS  = $(subst .c,.o,$(SET_RANDOM_BITS_CFILES))
 LIBOCFS2 = ../libocfs2/libocfs2.a
 LIBS = $(LIBOCFS2) $(COM_ERR_LIBS)
 
@@ -51,4 +53,7 @@
 find_inode_paths: $(FIND_INODE_PATHS_OBJS) $(LIBS)
 	$(LINK) 
 
+set_random_bits: $(SET_RANDOM_BITS_OBJS) $(LIBS)
+	$(LINK) 
+
 include $(TOPDIR)/Postamble.make

Added: trunk/extras/set_random_bits.c
===================================================================
--- trunk/extras/set_random_bits.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/extras/set_random_bits.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -0,0 +1,225 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * set_random_bits.c
+ *
+ * Set a (not-so-random) pattern of alternating set bits on the global
+ * bitmap (or any file you give me the block offset of). Note that
+ * this will not clear any bits that have already been set.
+ *
+ * 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: Mark Fasheh
+ */
+
+#define _XOPEN_SOURCE 600  /* Triggers XOPEN2K in features.h */
+#define _LARGEFILE64_SOURCE
+
+#include <stdlib.h>
+#include <getopt.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdint.h>
+#include "ocfs2.h"
+
+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;
+}
+
+static void print_usage(void)
+{
+	fprintf(stderr,
+		"Usage: set_random_bits -i <inode_blkno> <filename>\n");
+}
+
+struct walk_block {
+	ocfs2_dinode *di;
+	char *buf;
+	uint32_t used;
+};
+
+#define BITCOUNT(x)     (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
+#define BX_(x)          ((x) - (((x)>>1)&0x77777777) \
+			     - (((x)>>2)&0x33333333) \
+			     - (((x)>>3)&0x11111111))
+
+static int walk_blocks_func(ocfs2_filesys *fs,
+			    uint64_t blkno,
+			    uint64_t bcount,
+			    void *priv_data)
+{
+	struct walk_block *wb = priv_data;
+	errcode_t ret;
+	int i;
+	uint32_t *up;
+
+	ret = io_read_block(fs->fs_io, blkno, 1, wb->buf);
+	if (ret) {
+		com_err("walk_blocks_func", ret,
+			"while reading block %"PRIu64, blkno);
+		return OCFS2_BLOCK_ABORT;
+	}
+
+	/* set every other bit */
+	up = (uint32_t *) wb->buf;
+	for(i = 0; i < (fs->fs_blocksize / sizeof(uint32_t)); i++) {
+		up[i] |= 0x55555555;
+		wb->used += BITCOUNT(up[i]);
+	}
+
+	ret = io_write_block(fs->fs_io, blkno, 1, wb->buf);
+	if (ret) {
+		com_err("walk_blocks_func", ret,
+			"while writing block %"PRIu64, blkno);
+		return OCFS2_BLOCK_ABORT;
+	}
+	return 0;
+}
+
+extern int opterr, optind;
+extern char *optarg;
+
+int main(int argc, char *argv[])
+{
+	errcode_t ret;
+	uint64_t blkno, sys_blkno;
+	int c;
+	char *filename, *buf;
+	const char *bitmap_name = 
+		ocfs2_system_inode_names[GLOBAL_BITMAP_SYSTEM_INODE];
+	ocfs2_filesys *fs;
+	ocfs2_dinode *di;
+	struct walk_block wb;
+
+	blkno = OCFS2_SUPER_BLOCK_BLKNO;
+
+	initialize_ocfs_error_table();
+
+	while ((c = getopt(argc, argv, "i:")) != EOF) {
+		switch (c) {
+			case 'i':
+				blkno = read_number(optarg);
+				if (blkno <= OCFS2_SUPER_BLOCK_BLKNO) {
+					fprintf(stderr,
+						"Invalid inode block: %s\n",
+						optarg);
+					print_usage();
+					return 1;
+				}
+				break;
+
+			default:
+				print_usage();
+				return 1;
+				break;
+		}
+	}
+
+	if (optind >= argc) {
+		fprintf(stderr, "Missing filename\n");
+		print_usage();
+		return 1;
+	}
+	filename = argv[optind];
+
+	ret = ocfs2_open(filename, OCFS2_FLAG_RW, 0, 0, &fs);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while opening file \"%s\"", filename);
+		goto out;
+	}
+
+	if (blkno == OCFS2_SUPER_BLOCK_BLKNO) {
+		sys_blkno = OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno;
+
+		ret = ocfs2_lookup(fs, sys_blkno, bitmap_name, 
+				   strlen(bitmap_name), NULL, &blkno);
+		if (ret) {
+			com_err(argv[0], ret,
+				"while looking up \"%s\"", bitmap_name);
+			goto out;
+		}
+	}
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while allocating inode buffer");
+		goto out_close;
+	}
+
+	memset(&wb, 0, sizeof(wb));
+
+	ret = ocfs2_read_inode(fs, blkno, buf);
+	if (ret) {
+		com_err(argv[0], ret, "while reading inode %"PRIu64, blkno);
+		goto out_free;
+	}
+
+	di = (ocfs2_dinode *)buf;
+
+	wb.di = di;
+	ret = ocfs2_malloc_block(fs->fs_io, &wb.buf);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while allocating block buffer");
+		goto out_free;
+	}
+
+	ret = ocfs2_block_iterate(fs, blkno, 0,
+				  walk_blocks_func,
+				  &wb);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while walking blocks");
+		goto out_free;
+	}
+
+	di->id1.bitmap1.i_used = wb.used;
+
+	ret = ocfs2_write_inode(fs, blkno, buf);
+	if (ret) {
+		com_err(argv[0], ret, "while reading inode %"PRIu64, blkno);
+		goto out_free;
+	}
+
+out_free:
+	if (wb.buf)
+		ocfs2_free(&wb.buf);
+
+	ocfs2_free(&buf);
+
+out_close:
+	ret = ocfs2_close(fs);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while closing file \"%s\"", filename);
+	}
+
+out:
+	return 0;
+}
+
+

Modified: trunk/libocfs2/Makefile
===================================================================
--- trunk/libocfs2/Makefile	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/Makefile	2004-10-02 01:22:53 UTC (rev 309)
@@ -35,13 +35,18 @@
 DEBUG_EXE_FILES = $(shell awk '/DEBUG_EXE/{if (k[FILENAME] == 0) {print FILENAME; k[FILENAME] = 1;}}' $(CFILES))
 DEBUG_EXE_PROGRAMS = $(addprefix debug_,$(subst .c,,$(DEBUG_EXE_FILES)))
 
+.SECONDARY:
+
 UNINST_PROGRAMS += $(DEBUG_EXE_PROGRAMS)
 
-debug_%: %.c libocfs2.a
+debug_%.o : %.c 
 	$(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(LOCAL_CPPFLAGS) \
-		$(INCLUDES) $(DEFINES) $(VERMAGIC) \
-		$(COM_ERR_LIBS) -DDEBUG_EXE -o $@ $^
+		$(INCLUDES) $(DEFINES) \
+		-DDEBUG_EXE -o $@ -c $<
 
+debug_%: debug_%.o libocfs2.a
+	$(LINK) $(COM_ERR_LIBS)
+
 endif
 
 CFILES = 		\
@@ -66,6 +71,7 @@
 	unlink.c	\
 	bitmap.c	\
 	fileio.c	\
+	chain.c		\
 	checkhb.c	\
 	kernel-rbtree.c	\
 	bitops.c

Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/bitmap.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -266,14 +266,8 @@
 	    next->bc_start_bit)
 		return OCFS2_ET_INVALID_BIT;
 
-	/*
-	 * If at least one cpos is not zero, then these have real disk
-	 * locations, and they better be cpos contig as well.
-	 */
-	if ((prev->bc_cpos || next->bc_cpos) &&
-	    ((prev->bc_cpos +
-	     ((prev->bc_total_bits / 8) /
-	      bitmap->b_fs->fs_clusters)) != next->bc_cpos))
+	if (bitmap->b_ops->merge_cluster &&
+	    !(*bitmap->b_ops->merge_cluster)(bitmap, prev, next))
 		return OCFS2_ET_INVALID_BIT;
 
 	new_bits = (uint64_t)(prev->bc_total_bits) +
@@ -602,9 +596,9 @@
 		bc = rb_entry(node, struct ocfs2_bitmap_cluster, bc_node);
 
 		fprintf(stdout,
-			"(start: %"PRIu64", n: %d, set: %d, cpos: %"PRIu32")\n",
+			"(start: %"PRIu64", n: %d, set: %d)\n",
 			bc->bc_start_bit, bc->bc_total_bits,
-			bc->bc_set_bits, bc->bc_cpos);
+			bc->bc_set_bits);
 	}
 }
 

Added: trunk/libocfs2/chain.c
===================================================================
--- trunk/libocfs2/chain.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/chain.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -0,0 +1,411 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * chain.c
+ *
+ * Iterate over allocation chains.  Part of the OCFS2 userspace library.
+ *
+ * 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: Joel Becker
+ */
+
+#define _XOPEN_SOURCE 600  /* Triggers XOPEN2K in features.h */
+#define _LARGEFILE64_SOURCE
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "ocfs2.h"
+
+
+errcode_t ocfs2_read_group_desc(ocfs2_filesys *fs, uint64_t blkno,
+				char *gd_buf)
+{
+	errcode_t ret;
+	char *blk;
+	ocfs2_group_desc *gd;
+
+	if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
+	    (blkno > fs->fs_blocks))
+		return OCFS2_ET_BAD_BLKNO;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &blk);
+	if (ret)
+		return ret;
+
+	ret = io_read_block(fs->fs_io, blkno, 1, blk);
+	if (ret)
+		goto out;
+
+	gd = (ocfs2_group_desc *)blk;
+
+	ret = OCFS2_ET_BAD_GROUP_DESC_MAGIC;
+	if (memcmp(gd->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
+		   strlen(OCFS2_GROUP_DESC_SIGNATURE)))
+		goto out;
+
+	/* FIXME swap block */
+
+	memcpy(gd_buf, blk, fs->fs_blocksize);
+
+	ret = 0;
+out:
+	ocfs2_free(&blk);
+
+	return ret;
+}
+
+errcode_t ocfs2_write_group_desc(ocfs2_filesys *fs, uint64_t blkno,
+				 char *gd_buf)
+{
+	errcode_t ret;
+	char *blk;
+
+	if (!(fs->fs_flags & OCFS2_FLAG_RW))
+		return OCFS2_ET_RO_FILESYS;
+
+	if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
+	    (blkno > fs->fs_blocks))
+		return OCFS2_ET_BAD_BLKNO;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &blk);
+	if (ret)
+		return ret;
+
+	/* FIXME Swap block */
+
+	memcpy(blk, gd_buf, fs->fs_blocksize);
+
+	ret = io_write_block(fs->fs_io, blkno, 1, blk);
+	if (ret)
+		goto out;
+
+	fs->fs_flags |= OCFS2_FLAG_CHANGED;
+	ret = 0;
+
+out:
+	ocfs2_free(&blk);
+
+	return ret;
+}
+
+
+
+struct chain_context {
+	ocfs2_filesys *fs;
+	int (*func)(ocfs2_filesys *fs,
+		    uint64_t gd_blkno,
+		    int chain_num,
+		    void *priv_data);
+	errcode_t errcode;
+	char *gd_buf;
+	void *priv_data;
+};
+
+
+static int chain_iterate_gd(ocfs2_chain_rec *c_rec, int chain_num,
+			    struct chain_context *ctxt)
+{
+	int iret = 0;
+	uint64_t blkno;
+	ocfs2_group_desc *gd;
+
+	blkno = c_rec->c_blkno;
+
+	while (blkno) {
+		iret = (*ctxt->func)(ctxt->fs, blkno, chain_num,
+				     ctxt->priv_data);
+		if (iret & OCFS2_CHAIN_ABORT)
+			break;
+
+		ctxt->errcode = ocfs2_read_group_desc(ctxt->fs, blkno,
+						      ctxt->gd_buf);
+		if (ctxt->errcode) {
+			iret |= OCFS2_EXTENT_ERROR;
+			break;
+		}
+		gd = (ocfs2_group_desc *)ctxt->gd_buf;
+
+		if ((gd->bg_blkno != blkno) ||
+		    (gd->bg_chain != chain_num)) {
+			ctxt->errcode = OCFS2_ET_CORRUPT_GROUP_DESC;
+			iret |= OCFS2_CHAIN_ERROR;
+			break;
+		}
+
+		blkno = gd->bg_next_group;
+	}
+
+	return iret;
+}
+
+static int chain_iterate_cl(ocfs2_chain_list *cl,
+			    struct chain_context *ctxt)
+{
+	int iret = 0;
+	int i;
+
+	for (i = 0; i < cl->cl_next_free_rec; i++) {
+		iret |= chain_iterate_gd(&cl->cl_recs[i], i, ctxt);
+		if (iret & (OCFS2_CHAIN_ABORT | OCFS2_CHAIN_ERROR))
+			break;
+	}
+
+	if (iret & OCFS2_CHAIN_CHANGED) {
+		/* Something here ? */
+	}
+
+	return iret;
+}
+
+errcode_t ocfs2_chain_iterate(ocfs2_filesys *fs,
+			      uint64_t blkno,
+			      int (*func)(ocfs2_filesys *fs,
+					  uint64_t gd_blkno,
+					  int chain_num,
+					  void *priv_data),
+			       void *priv_data)
+{
+	int iret = 0;
+	char *buf;
+	ocfs2_dinode *inode;
+	errcode_t ret;
+	struct chain_context ctxt;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_read_inode(fs, blkno, buf);
+	if (ret)
+		goto out_buf;
+
+	inode = (ocfs2_dinode *)buf;
+
+	ret = OCFS2_ET_INODE_NOT_VALID;
+	if (!(inode->i_flags & OCFS2_VALID_FL))
+		goto out_buf;
+
+	ret = OCFS2_ET_INODE_CANNOT_BE_ITERATED;
+	if (!(inode->i_flags & OCFS2_CHAIN_FL))
+		goto out_buf;
+
+	ret = ocfs2_malloc0(fs->fs_blocksize, &ctxt.gd_buf);
+	if (ret)
+		goto out_gd_buf;
+
+	ctxt.fs = fs;
+	ctxt.func = func;
+	ctxt.priv_data = priv_data;
+
+	ret = 0;
+	iret |= chain_iterate_cl(&inode->id2.i_chain, &ctxt);
+	if (iret & OCFS2_EXTENT_ERROR)
+		ret = ctxt.errcode;
+
+	if (iret & OCFS2_EXTENT_CHANGED) {
+		/* Do something */
+	}
+
+out_gd_buf:
+	if (ctxt.gd_buf)
+		ocfs2_free(&ctxt.gd_buf);
+
+out_buf:
+	ocfs2_free(&buf);
+
+	return ret;
+}
+
+
+#ifdef DEBUG_EXE
+#include <stdlib.h>
+#include <getopt.h>
+
+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;
+}
+
+static void print_usage(void)
+{
+	fprintf(stderr,
+		"Usage: debug_chain -i <inode_blkno> <filename>\n");
+}
+
+struct walk_it {
+	ocfs2_dinode *di;
+	char *gd_buf;
+	int last_chain;
+	int count_free;
+	int count_total;
+};
+
+static int walk_chain_func(ocfs2_filesys *fs,
+			   uint64_t gd_blkno,
+			   int chain_num,
+			   void *priv_data)
+{
+	struct walk_it *wi = priv_data;
+	ocfs2_group_desc *gd;
+	errcode_t ret;
+
+	if (wi->last_chain != chain_num) {
+		fprintf(stdout, "CHAIN[%02d]: %d/%d\n", chain_num,
+			wi->di->id2.i_chain.cl_recs[chain_num].c_free,
+			wi->di->id2.i_chain.cl_recs[chain_num].c_total);
+		wi->last_chain = chain_num;
+		wi->count_free = wi->count_total = 0;
+	}
+
+	ret = ocfs2_read_group_desc(fs, gd_blkno, wi->gd_buf);
+	if (ret)
+		return OCFS2_CHAIN_ERROR;
+
+	gd = (ocfs2_group_desc *)wi->gd_buf;
+	wi->count_free += gd->bg_free_bits_count;
+	wi->count_total += gd->bg_bits;
+	fprintf(stdout, "    % 16"PRIu64": %05d/%05d = %05d/%05d\n",
+		gd->bg_blkno,
+		gd->bg_free_bits_count, gd->bg_bits,
+		wi->count_free, wi->count_total);
+
+	return 0;
+}
+
+
+extern int opterr, optind;
+extern char *optarg;
+
+int main(int argc, char *argv[])
+{
+	errcode_t ret;
+	uint64_t blkno;
+	int c;
+	char *filename, *buf;
+	ocfs2_filesys *fs;
+	ocfs2_dinode *di;
+	struct walk_it wi;
+
+	blkno = OCFS2_SUPER_BLOCK_BLKNO;
+
+	initialize_ocfs_error_table();
+
+	while ((c = getopt(argc, argv, "bei:")) != EOF) {
+		switch (c) {
+			case 'i':
+				blkno = read_number(optarg);
+				if (blkno <= OCFS2_SUPER_BLOCK_BLKNO) {
+					fprintf(stderr,
+						"Invalid inode block: %s\n",
+						optarg);
+					print_usage();
+					return 1;
+				}
+				break;
+
+			default:
+				print_usage();
+				return 1;
+				break;
+		}
+	}
+	
+	if (blkno == OCFS2_SUPER_BLOCK_BLKNO) {
+		fprintf(stderr, "You must specify an inode block\n");
+		print_usage();
+		return 1;
+	}
+
+	if (optind >= argc) {
+		fprintf(stderr, "Missing filename\n");
+		print_usage();
+		return 1;
+	}
+	filename = argv[optind];
+	
+	ret = ocfs2_open(filename, OCFS2_FLAG_RO, 0, 0, &fs);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while opening file \"%s\"", filename);
+		goto out;
+	}
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while allocating inode buffer");
+		goto out_close;
+	}
+
+	memset(&wi, 0, sizeof(wi));
+
+	ret = ocfs2_read_inode(fs, blkno, buf);
+	if (ret) {
+		com_err(argv[0], ret, "while reading inode %"PRIu64, blkno);
+		goto out_free;
+	}
+
+	di = (ocfs2_dinode *)buf;
+
+	fprintf(stdout, "OCFS2 inode %"PRIu64" on \"%s\"\n",
+		blkno, filename);
+
+	ret = ocfs2_malloc_block(fs->fs_io, &wi.gd_buf);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while allocating gd buffer");
+		goto out_free;
+	}
+
+	wi.di = di;
+	wi.last_chain = -1;
+	ret = ocfs2_chain_iterate(fs, blkno,
+				  walk_chain_func,
+				  &wi);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while walking extents");
+	}
+
+out_free:
+	if (wi.gd_buf)
+		ocfs2_free(&wi.gd_buf);
+
+	ocfs2_free(&buf);
+
+out_close:
+	ret = ocfs2_close(fs);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while closing file \"%s\"", filename);
+	}
+
+out:
+	return 0;
+}
+#endif  /* DEBUG_EXE */
+
+

Modified: trunk/libocfs2/extent_map.c
===================================================================
--- trunk/libocfs2/extent_map.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/extent_map.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -34,6 +34,8 @@
 
 #include "extent_map.h"
 
+/* FIXME: Use rbtrees.  Add lookup */
+
 struct extent_map_context {
 	ocfs2_cached_inode *cinode;
 	errcode_t errcode;

Modified: trunk/libocfs2/extents.c
===================================================================
--- trunk/libocfs2/extents.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/extents.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -207,8 +207,8 @@
 
 	flags = extent_iterate_el(el, eb_rec->e_blkno, ctxt);
 	changed |= flags;
-	if (flags & OCFS2_EXTENT_ABORT)
-		iret |= OCFS2_EXTENT_ABORT;
+	if (flags & (OCFS2_EXTENT_ABORT | OCFS2_EXTENT_ERROR))
+		iret |= flags & (OCFS2_EXTENT_ABORT | OCFS2_EXTENT_ERROR);
 
 	if (changed & OCFS2_EXTENT_CHANGED) {
 		/* Do something */
@@ -216,7 +216,7 @@
 
 	if ((ctxt->flags & OCFS2_EXTENT_FLAG_DEPTH_TRAVERSE) &&
 	    !(ctxt->flags & OCFS2_EXTENT_FLAG_DATA_ONLY) &&
-	    !(iret & OCFS2_EXTENT_ABORT))
+	    !(iret & (OCFS2_EXTENT_ABORT|OCFS2_EXTENT_ERROR)))
 		iret = (*ctxt->func)(ctxt->fs, eb_rec,
 				     ref_tree_depth,
 				     ctxt->ccount, ref_blkno,

Modified: trunk/libocfs2/include/bitmap.h
===================================================================
--- trunk/libocfs2/include/bitmap.h	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/include/bitmap.h	2004-10-02 01:22:53 UTC (rev 309)
@@ -29,6 +29,20 @@
 
 #include "kernel-rbtree.h"
 
+struct ocfs2_bitmap_cluster {
+	struct rb_node bc_node;
+	uint64_t bc_start_bit;		/* Bit offset.  Must be
+					   aligned on
+					   (clustersize * 8) */
+	int bc_total_bits;		/* set_bit() and friends can't
+					   handle bitmaps larger than
+					   int offsets */
+	int bc_set_bits;
+	char *bc_bitmap;
+
+	void *bc_private;
+};
+
 struct ocfs2_bitmap_operations {
 	errcode_t (*set_bit)(ocfs2_bitmap *bm, uint64_t bit,
 			     int *oldval);
@@ -36,6 +50,9 @@
 			       int *oldval);
 	errcode_t (*test_bit)(ocfs2_bitmap *bm, uint64_t bit,
 			      int *val);
+	errcode_t (*merge_cluster)(ocfs2_bitmap *bm,
+				   struct ocfs2_bitmap_cluster *prev,
+				   struct ocfs2_bitmap_cluster *next);
 	errcode_t (*read_bitmap)(ocfs2_bitmap *bm);
 	errcode_t (*write_bitmap)(ocfs2_bitmap *bm);
 	void (*destroy_notify)(ocfs2_bitmap *bm);
@@ -56,21 +73,7 @@
 	void *b_private;
 };
 
-struct ocfs2_bitmap_cluster {
-	struct rb_node bc_node;
-	uint64_t bc_start_bit;		/* Bit offset.  Must be
-					   aligned on
-					   (clustersize * 8) */
-	int bc_total_bits;		/* set_bit() and friends can't
-					   handle bitmaps larger than
-					   int offsets */
-	int bc_set_bits;
-	uint32_t bc_cpos;		/* If this bitmap is stored
-					   on disk, where it lives */
-	char *bc_bitmap;
-};
 
-
 errcode_t ocfs2_bitmap_new(ocfs2_filesys *fs,
 			   uint64_t total_bits,
 			   const char *description,

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/include/ocfs2.h	2004-10-02 01:22:53 UTC (rev 309)
@@ -98,7 +98,7 @@
 /* Return flags for the block iterator functions */
 #define OCFS2_BLOCK_CHANGED	0x01
 #define OCFS2_BLOCK_ABORT	0x02
-#define OCFS2_BLOCK_ERROR	0x03
+#define OCFS2_BLOCK_ERROR	0x04
 
 /*
  * Block iterate flags
@@ -116,14 +116,20 @@
 
 
 /* Return flags for the directory iterator functions */
-#define OCFS2_DIRENT_CHANGED	1
-#define OCFS2_DIRENT_ABORT	2
-#define OCFS2_DIRENT_ERROR	3
+#define OCFS2_DIRENT_CHANGED	0x01
+#define OCFS2_DIRENT_ABORT	0x02
+#define OCFS2_DIRENT_ERROR	0x04
 
 /* Directory iterator flags */
-#define OCFS2_DIRENT_FLAG_INCLUDE_EMPTY		1
-#define OCFS2_DIRENT_FLAG_INCLUDE_REMOVED	2
+#define OCFS2_DIRENT_FLAG_INCLUDE_EMPTY		0x01
+#define OCFS2_DIRENT_FLAG_INCLUDE_REMOVED	0x02
 
+/* Return flags for the chain iterator functions */
+#define OCFS2_CHAIN_CHANGED	0x01
+#define OCFS2_CHAIN_ABORT	0x02
+#define OCFS2_CHAIN_ERROR	0x04
+
+
 /* Directory constants */
 #define OCFS2_DIRENT_DOT_FILE		1
 #define OCFS2_DIRENT_DOT_DOT_FILE	2
@@ -131,11 +137,11 @@
 #define OCFS2_DIRENT_DELETED_FILE	4
 
 /* Check if mounted flags */
-#define OCFS2_MF_MOUNTED         1
-#define OCFS2_MF_ISROOT          2
-#define OCFS2_MF_READONLY        4
-#define OCFS2_MF_SWAP            8
-#define OCFS2_MF_MOUNTED_CLUSTER 16
+#define OCFS2_MF_MOUNTED         0x01
+#define OCFS2_MF_ISROOT          0x02
+#define OCFS2_MF_READONLY        0x04
+#define OCFS2_MF_SWAP            0x08
+#define OCFS2_MF_MOUNTED_CLUSTER 0x16
 
 /* Some constants used in heartbeat */
 #define OCFS2_NODE_MAP_MAX_NODES	256
@@ -359,4 +365,18 @@
 errcode_t ocfs2_get_ocfs1_label(char *device, uint8_t *label, uint16_t label_len,
 				uint8_t *uuid, uint16_t uuid_len);
 
+errcode_t ocfs2_read_group_desc(ocfs2_filesys *fs, uint64_t blkno,
+				char *gd_buf);
+
+errcode_t ocfs2_write_group_desc(ocfs2_filesys *fs, uint64_t blkno,
+				 char *gd_buf);
+
+errcode_t ocfs2_chain_iterate(ocfs2_filesys *fs,
+			      uint64_t blkno,
+			      int (*func)(ocfs2_filesys *fs,
+					  uint64_t gd_blkno,
+					  int chain_num,
+					  void *priv_data),
+			      void *priv_data);
+
 #endif  /* _FILESYS_H */

Modified: trunk/libocfs2/include/ocfs2_fs.h
===================================================================
--- trunk/libocfs2/include/ocfs2_fs.h	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/include/ocfs2_fs.h	2004-10-02 01:22:53 UTC (rev 309)
@@ -56,6 +56,7 @@
 #define OCFS2_SUPER_BLOCK_SIGNATURE	"OCFSV2"
 #define OCFS2_INODE_SIGNATURE		"INODE01"
 #define OCFS2_EXTENT_BLOCK_SIGNATURE	"EXBLK01"
+#define OCFS2_GROUP_DESC_SIGNATURE      "GROUP01"
 
 /* Compatibility flags */
 #define OCFS2_HAS_COMPAT_FEATURE(sb,mask)			\
@@ -96,7 +97,7 @@
 #define OCFS2_BITMAP_FL		(0x00000080)	/* Allocation bitmap */
 #define OCFS2_JOURNAL_FL	(0x00000100)	/* Node journal */
 #define OCFS2_DLM_FL		(0x00000200)	/* DLM area */
-	
+#define OCFS2_CHAIN_FL		(0x00000400)	/* Chain allocator */
 
 /* Limit of space in ocfs2_dir_entry */
 #define OCFS2_MAX_FILENAME_LENGTH       255
@@ -117,16 +118,13 @@
 enum {
 	BAD_BLOCK_SYSTEM_INODE = 0,
 	GLOBAL_INODE_ALLOC_SYSTEM_INODE,
-	GLOBAL_INODE_ALLOC_BITMAP_SYSTEM_INODE,
 	DLM_SYSTEM_INODE,
 #define OCFS2_FIRST_ONLINE_SYSTEM_INODE DLM_SYSTEM_INODE
 	GLOBAL_BITMAP_SYSTEM_INODE,
 	ORPHAN_DIR_SYSTEM_INODE,
 #define OCFS2_LAST_GLOBAL_SYSTEM_INODE ORPHAN_DIR_SYSTEM_INODE
 	EXTENT_ALLOC_SYSTEM_INODE,
-	EXTENT_ALLOC_BITMAP_SYSTEM_INODE,
 	INODE_ALLOC_SYSTEM_INODE,
-	INODE_ALLOC_BITMAP_SYSTEM_INODE,
 	JOURNAL_SYSTEM_INODE,
 	LOCAL_ALLOC_SYSTEM_INODE,
 	NUM_SYSTEM_INODES
@@ -134,10 +132,9 @@
 
 static char *ocfs2_system_inode_names[NUM_SYSTEM_INODES] = {
 	/* Global system inodes (single copy) */
-	/* The first three are only used from userspace mfks/tunefs */
+	/* The first two are only used from userspace mfks/tunefs */
 	[BAD_BLOCK_SYSTEM_INODE]		"bad_blocks",
 	[GLOBAL_INODE_ALLOC_SYSTEM_INODE] 	"global_inode_alloc",
-	[GLOBAL_INODE_ALLOC_BITMAP_SYSTEM_INODE]	"global_inode_alloc_bitmap",
 
 	/* These are used by the running filesystem */
 	[DLM_SYSTEM_INODE]			"dlm",
@@ -146,9 +143,7 @@
 
 	/* Node-specific system inodes (one copy per node) */
 	[EXTENT_ALLOC_SYSTEM_INODE]		"extent_alloc:%04d",
-	[EXTENT_ALLOC_BITMAP_SYSTEM_INODE]	"extent_alloc_bitmap:%04d",
 	[INODE_ALLOC_SYSTEM_INODE]		"inode_alloc:%04d",
-	[INODE_ALLOC_BITMAP_SYSTEM_INODE]	"inode_alloc_bitmap:%04d",
 	[JOURNAL_SYSTEM_INODE]			"journal:%04d",
 	[LOCAL_ALLOC_SYSTEM_INODE]		"local_alloc:%04d"
 };
@@ -227,6 +222,12 @@
 /*10*/
 } ocfs2_extent_rec;	
 
+typedef struct _ocfs2_chain_rec {
+	__u32 c_free;	/* Number of free bits in this chain. */
+	__u32 c_total;	/* Number of total bits in this chain */
+	__u64 c_blkno;	/* Physical disk offset (blocks) of 1st group */
+} ocfs2_chain_rec;
+
 /*
  * On disk extent list for OCFS2 (node in the tree).  Note that this
  * is contained inside ocfs2_dinode or ocfs2_extent_block, so the
@@ -247,16 +248,30 @@
 } ocfs2_extent_list;
 
 /*
+ * On disk allocation chain list for OCFS2.  Note that this is
+ * contained inside ocfs2_dinode, so the offsets are relative to
+ * ocfs2_dinode.id2.i_chain.
+ */
+typedef struct _ocfs2_chain_list {
+/*00*/	__u16 cl_cpg;			/* Clusters per Block Group */
+	__u16 cl_bpc;			/* Bits per cluster */
+	__u16 cl_count;			/* Total chains in this list */
+	__u16 cl_next_free_rec;		/* Next unused chain slot */
+	__u64 cl_reserved1;
+/*10*/	ocfs2_chain_rec cl_recs[0];	/* Chain records */
+} ocfs2_chain_list;
+
+/*
  * On disk extent block (indirect block) for OCFS2
  */
 typedef struct _ocfs2_extent_block
 {
 /*00*/	__u8 h_signature[8];		/* Signature for verification */
-	__u64 h_suballoc_blkno;		/* Node suballocator offset,
-					   in blocks */
+	__u64 h_reserved1;
 /*10*/	__s16 h_suballoc_node;		/* Node suballocator this
 					   extent_header belongs to */
-	__u16 h_reserved1;
+	__u16 h_suballoc_bit;		/* Bit offset in suballocater
+					   block group */
 	__u32 h_reserved2;
 	__u64 h_blkno;			/* Offset on disk, in blocks */
 /*20*/	__u64 h_parent_blk;		/* Offset on disk, in blocks,
@@ -275,13 +290,9 @@
 typedef struct _ocfs2_disk_lock
 {
 /*00*/	__s16 dl_master;	/* Node number of current master */
-	__u16 dl_reserved1;
 	__u8 dl_level;		/* Lock level */
-	__u8 dl_reserved2[3];	/* Pad to u64 */
-	__u64 dl_seq_num;	/* Lock transaction seqnum */
-/*10*/	__u32 dl_node_map[8];	/* Bitmap of interested nodes,
-				   was __u32 */ 
-/*30*/
+	__u8 dl_reserved1;
+/*04*/
 } ocfs2_disk_lock;
 
 /*
@@ -341,45 +352,43 @@
 typedef struct _ocfs2_dinode {
 /*00*/	__u8 i_signature[8];		/* Signature for validation */
 	__u32 i_generation;		/* Generation number */
-	__u16 i_reserved1;
 	__s16 i_suballoc_node;		/* Node suballocater this inode
 					   belongs to */
-/*10*/	__u64 i_suballoc_blkno;		/* Node suballocator offset,
-       					   in blocks */
-/*18*/	ocfs2_disk_lock i_disk_lock;	/* Lock structure */
-/*48*/	__u32 i_uid;			/* Owner UID */
+	__u16 i_suballoc_bit;		/* Bit offset in suballocater
+					   block group */
+/*10*/	ocfs2_disk_lock i_disk_lock;	/* Lock structure */
+/*14*/	__u32 i_clusters;		/* Cluster count */
+/*18*/	__u32 i_uid;			/* Owner UID */
 	__u32 i_gid;			/* Owning GID */
-/*50*/	__u64 i_size;			/* Size in bytes */
+/*20*/	__u64 i_size;			/* Size in bytes */
 	__u16 i_mode;			/* File mode */
 	__u16 i_links_count;		/* Links count */
 	__u32 i_flags;			/* File flags */
-/*60*/	__u64 i_atime;			/* Access time */
+/*30*/	__u64 i_atime;			/* Access time */
 	__u64 i_ctime;			/* Creation time */
-/*70*/	__u64 i_mtime;			/* Modification time */
+/*40*/	__u64 i_mtime;			/* Modification time */
 	__u64 i_dtime;			/* Deletion time */
-/*80*/	__u64 i_blkno;			/* Offset on disk, in blocks */
-	__u32 i_clusters;		/* Cluster count */
-	__u32 i_reserved2;
-/*90*/	__u64 i_last_eb_blk;		/* Pointer to last extent
+/*50*/	__u64 i_blkno;			/* Offset on disk, in blocks */
+	__u64 i_last_eb_blk;		/* Pointer to last extent
 					   block */
-	__u64 i_reserved3;
-/*A0*/	__u64 i_reserved4;
-	__u64 i_reserved5;
-/*B0*/	__u64 i_reserved6;
-	union {
-		__u64 i_pad1;		/* Generic way to refer to this 64bit
-					   union */
+/*60*/	__u64 i_reserved1[11];
+/*B8*/	union {
+		__u64 i_pad1;		/* Generic way to refer to this
+					   64bit union */
 		struct {
 			__u64 i_rdev;	/* Device number */
 		} dev1;
-		struct {		/* Info for bitmap system inodes */
+		struct {		/* Info for bitmap system
+					   inodes */
 			__u32 i_used;	/* Bits (ie, clusters) used  */
-			__u32 i_total;	/* Total bits (clusters) available */
+			__u32 i_total;	/* Total bits (clusters)
+					   available */
 		} bitmap1;
 	} id1;				/* Inode type dependant 1 */
 /*C0*/	union {
 		ocfs2_super_block i_super;
-                ocfs2_local_alloc i_lab;
+		ocfs2_local_alloc i_lab;
+		ocfs2_chain_list  i_chain;
 		ocfs2_extent_list i_list;
 	} id2;
 /* Actual on-disk size is one block */
@@ -397,8 +406,29 @@
 /* Actual on-disk length specified by rec_len */
 };
 
+/*
+ * On disk allocator group structure for OCFS2
+ */
+typedef struct _ocfs2_group_desc
+{
+/*00*/	__u8    bg_signature[8];        /* Signature for validation */
+	__u16   bg_size;                /* Size of included bitmap in
+					   bytes. */
+	__u16   bg_bits;                /* Bits represented by this
+					   group. */
+	__u16	bg_free_bits_count;     /* Free bits count */
+	__u16   bg_chain;               /* What chain I am in. */
+/*10*/	__u32   bg_generation;
+	__u32	bg_reserved1;
+	__u64   bg_next_group;          /* Next group in my list, in
+					   blocks */
+/*20*/	__u64   bg_parent_dinode;       /* dinode which owns me, in
+					   blocks */
+	__u64   bg_blkno;               /* Offset on disk, in blocks */
+/*30*/	__u64   bg_reserved2[2];
+/*40*/	__u8    bg_bitmap[0];
+} ocfs2_group_desc;
 
-
 #ifdef __KERNEL__
 static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
 {
@@ -410,6 +440,16 @@
 	return size / sizeof(struct _ocfs2_extent_rec);
 }
 
+static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct _ocfs2_dinode, id2.i_chain.cl_recs);
+
+	return size / sizeof(struct _ocfs2_chain_rec);
+}
+
 static inline int ocfs2_extent_recs_per_eb(struct super_block *sb)
 {
 	int size;
@@ -429,6 +469,16 @@
 
 	return size;
 }
+
+static inline int ocfs2_group_bitmap_size(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct _ocfs2_group_desc, bg_bitmap);
+
+	return size;
+}
 #else
 static inline int ocfs2_extent_recs_per_inode(int blocksize)
 {
@@ -440,6 +490,16 @@
 	return size / sizeof(struct _ocfs2_extent_rec);
 }
 
+static inline int ocfs2_chain_recs_per_inode(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct _ocfs2_dinode, id2.i_chain.cl_recs);
+
+	return size / sizeof(struct _ocfs2_chain_rec);
+}
+
 static inline int ocfs2_extent_recs_per_eb(int blocksize)
 {
 	int size;
@@ -459,6 +519,16 @@
 
 	return size;
 }
+
+static inline int ocfs2_group_bitmap_size(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct _ocfs2_group_desc, bg_bitmap);
+
+	return size;
+}
 #endif  /* __KERNEL__ */
 
 

Modified: trunk/libocfs2/inode_scan.c
===================================================================
--- trunk/libocfs2/inode_scan.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/inode_scan.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -45,104 +45,150 @@
 	int next_inode_file;
 	ocfs2_cached_inode *cur_inode_alloc;
 	ocfs2_cached_inode **inode_alloc;
-	ocfs2_extent_map_entry *cur_entry;
+	ocfs2_chain_rec *cur_rec;
+	int next_rec;
+	ocfs2_group_desc *cur_desc;
+	unsigned int count;
 	uint64_t cur_blkno;
-	char *extent_buffer;
+	char *group_buffer;
 	char *cur_block;
-	uint32_t buffer_clusters;
-	uint64_t blocks_in_buffer;
-	uint64_t blocks_left;
-	uint32_t cpos;
+	int buffer_blocks;
+	int blocks_in_buffer;
+	unsigned int blocks_left;
+	uint64_t bpos;
 	int c_to_b_bits;
 };
 
 
 /*
- * This function is called by fill_extent_buffer when an extent has
- * been completely read.  It must not be called from the last extent.
+ * This function is called by fill_group_buffer when an alloc group has
+ * been completely read.  It must not be called from the last group.
  * ocfs2_get_next_inode() should have detected that condition.
  */
-static errcode_t get_next_extent(ocfs2_inode_scan *scan)
+static errcode_t get_next_group(ocfs2_inode_scan *scan)
 {
-	struct list_head *pos;
-	ocfs2_extent_map *em;
+	errcode_t ret;
 
-	em = scan->cur_inode_alloc->ci_map;
-	pos = scan->cur_entry->e_list.next;
-	if (pos == &em->em_extents)
+	if (!scan->cur_desc) {
+		if (scan->bpos)
+			abort();
+
+		ret = ocfs2_malloc_block(scan->fs->fs_io,
+					 &scan->cur_desc);
+		if (ret)
+			return ret;
+	}
+
+	if (scan->bpos)
+		scan->cur_blkno = scan->cur_desc->bg_next_group;
+
+	/*
+	 * scan->cur_blkno better be nonzero, either set by
+	 * get_next_chain() or valid from bg_next_group
+	 */ 
+	if (!scan->cur_blkno)
 		abort();
-	scan->cur_entry = list_entry(pos, ocfs2_extent_map_entry,
-				     e_list);
-	if (scan->cur_entry->e_rec.e_cpos != scan->cpos)
-		return OCFS2_ET_CORRUPT_EXTENT_BLOCK;
 
-	scan->cur_blkno = scan->cur_entry->e_rec.e_blkno;
+	ret = io_read_block(scan->fs->fs_io, scan->cur_blkno, 1,
+			    (char *)scan->cur_desc);
+	if (ret)
+		return (ret);
 
+	if (scan->cur_desc->bg_blkno != scan->cur_blkno)
+		return OCFS2_ET_CORRUPT_GROUP_DESC;
+
+	/* Skip past group descriptor block */
+	scan->cur_blkno++;
+	scan->count++;
+	scan->blocks_left--;
+	scan->bpos = scan->cur_blkno;
+
 	return 0;
 }
 
 /*
+ * This function is called by fill_group_buffer when an alloc chain
+ * has been completely read.  It must not be called  when the current
+ * inode alloc file has been read in its entirety.  This condition
+ * should have been detected by ocfs2_get_next_inode().
+ */
+static errcode_t get_next_chain(ocfs2_inode_scan *scan)
+{
+	ocfs2_dinode *di = scan->cur_inode_alloc->ci_inode;
+
+	if (scan->next_rec == di->id2.i_chain.cl_next_free_rec) {
+		if (!scan->next_rec) {
+			/*
+			 * The only way we can get here with next_rec
+			 * == cl_next_free_rec == 0 is if
+			 * bitmap1.i_total was non-zero.  But if i_total
+			 * was non-zero and we have no chains, we're
+			 * corrupt.
+			 */
+			return OCFS2_ET_CORRUPT_CHAIN;
+		} else
+			abort();
+	}
+
+	scan->cur_rec = &di->id2.i_chain.cl_recs[scan->next_rec];
+	scan->next_rec++;
+	scan->count = 0;
+	scan->bpos = 0;
+	scan->cur_blkno = scan->cur_rec->c_blkno;
+
+	return 0;
+}
+
+/*
  * This function is called by ocfs2_get_next_inode when it needs
  * to read in more clusters from the current inode alloc file.  It
  * must not be called when the current inode alloc file has been read
  * in its entirety.  This condition is detected by
  * ocfs2_get_next_inode().
  */
-static errcode_t fill_extent_buffer(ocfs2_inode_scan *scan)
+static errcode_t fill_group_buffer(ocfs2_inode_scan *scan)
 {
 	errcode_t ret;
-	uint64_t num_blocks;
-	uint32_t num_clusters;
+	int num_blocks;
 
-	if (scan->cpos > (scan->cur_entry->e_rec.e_cpos +
-			  scan->cur_entry->e_rec.e_clusters))
+	if (scan->cur_rec && (scan->count > scan->cur_rec->c_total))
+	    abort();
+
+	if (scan->cur_rec && (scan->bpos > (scan->cur_desc->bg_blkno +
+			  scan->cur_desc->bg_bits)))
 		abort();
 
-	if (scan->cpos == (scan->cur_entry->e_rec.e_cpos +
-			   scan->cur_entry->e_rec.e_clusters)) {
-		ret = get_next_extent(scan);
+	if (!scan->cur_rec || (scan->count == scan->cur_rec->c_total)) {
+		ret = get_next_chain(scan);
 		if (ret)
 			return ret;
 	}
+	
+	if (!scan->bpos || (scan->bpos == (scan->cur_desc->bg_blkno +
+					   scan->cur_desc->bg_bits))) {
+		ret = get_next_group(scan);
+		if (ret)
+			return ret;
+	}
 
-	num_clusters = scan->cur_entry->e_rec.e_clusters -
-		(scan->cpos - scan->cur_entry->e_rec.e_cpos);
 
-	if (num_clusters > scan->buffer_clusters)
-		num_clusters = scan->buffer_clusters;
+	num_blocks = (scan->cur_desc->bg_blkno +
+		      scan->cur_desc->bg_bits) - scan->bpos;
 
-	num_blocks = (uint64_t)num_clusters << scan->c_to_b_bits;
+	if (num_blocks > scan->buffer_blocks)
+		num_blocks = scan->buffer_blocks;
+
 	ret = io_read_block(scan->fs->fs_io,
 			    scan->cur_blkno,
 			    num_blocks,
-			    scan->extent_buffer);
+			    scan->group_buffer);
 	if (ret)
 		return ret;
 
-	scan->cpos += num_clusters;
+	scan->bpos += num_blocks;
 	scan->blocks_in_buffer = num_blocks;
-	scan->cur_block = scan->extent_buffer;
+	scan->cur_block = scan->group_buffer;
 
-	if (!scan->cur_blkno) {
-		/*
-		 * inode_alloc[0] is the global inode allocator.  It
-		 * contains the first extent of the filesystem,
-		 * including block zero.  If this is that allocator
-		 * skip it past the superblock inode.
-		 *
-		 * (next_inode_file is one because we just incremented
-		 *  it.)
-		 */
-		if (scan->next_inode_file == 1) {
-			scan->cur_blkno = OCFS2_SUPER_BLOCK_BLKNO + 1;
-			scan->cur_block += (scan->cur_blkno *
-					    scan->fs->fs_blocksize);
-			scan->blocks_left -= scan->cur_blkno;
-			scan->blocks_in_buffer -= scan->cur_blkno;
-		}
-		/* FIXME: error otherwise */
-	}
-
 	return 0;
 }
 
@@ -151,7 +197,7 @@
 {
 	ocfs2_cached_inode *cinode = scan->cur_inode_alloc;
 
-	if (cinode && (scan->cpos != cinode->ci_inode->i_clusters))
+	if (cinode && scan->blocks_left)
 		abort();
 
 	do {
@@ -163,15 +209,14 @@
 		cinode = scan->cur_inode_alloc;
 
 		scan->next_inode_file++;
-	} while (list_empty(&cinode->ci_map->em_extents));
+	} while (!cinode->ci_inode->id1.bitmap1.i_total);
 
-	scan->cur_entry = list_entry(cinode->ci_map->em_extents.next,
-				     ocfs2_extent_map_entry, e_list);
-	scan->cpos = scan->cur_entry->e_rec.e_cpos;
-	/* could check cpos == 0 */
-	scan->cur_blkno = scan->cur_entry->e_rec.e_blkno;
+	scan->next_rec = 0;
+	scan->count = 0;
+	scan->cur_blkno = 0;
+	scan->cur_rec = 0;
 	scan->blocks_left =
-		cinode->ci_inode->i_clusters << scan->c_to_b_bits;
+		cinode->ci_inode->id1.bitmap1.i_total;
 
 	return 0;
 }
@@ -192,12 +237,12 @@
 	}
 
 	if (!scan->blocks_in_buffer) {
-		ret = fill_extent_buffer(scan);
+		ret = fill_group_buffer(scan);
 		if (ret)
 			return ret;
 	}
 	
-	/* Should swap the inode */
+	/* FIXME: Should swap the inode */
 	memcpy(inode, scan->cur_block, scan->fs->fs_blocksize);
 
 	scan->cur_block += scan->fs->fs_blocksize;
@@ -205,6 +250,7 @@
 	scan->blocks_left--;
 	*blkno = scan->cur_blkno;
 	scan->cur_blkno++;
+	scan->count++;
 
 	return 0;
 }
@@ -236,16 +282,17 @@
 		goto out_scan;
 
 	/* Minimum 8 inodes in the buffer */
-	if ((fs->fs_clustersize / fs->fs_blocksize) < 8) {
-		scan->buffer_clusters =
+	scan->buffer_blocks = fs->fs_clustersize / fs->fs_blocksize;
+	if (scan->buffer_blocks < 8) {
+		scan->buffer_blocks =
 			((8 * fs->fs_blocksize) +
 			 (fs->fs_clustersize - 1)) /
 			fs->fs_clustersize;
-	} else {
-		scan->buffer_clusters = 1;
+		scan->buffer_blocks <<= scan->c_to_b_bits;
 	}
-	ret = ocfs2_malloc(sizeof(char) * scan->buffer_clusters *
-			   fs->fs_clustersize, &scan->extent_buffer);
+
+	ret = ocfs2_malloc(sizeof(char) * scan->buffer_blocks *
+			   fs->fs_blocksize, &scan->group_buffer);
 	if (ret)
 		goto out_inode_files;
 
@@ -274,11 +321,10 @@
 			goto out_cleanup;
 	}
 
-	for (i = 0; i < scan->num_inode_alloc; i++) {
-		ret = ocfs2_load_extent_map(fs, scan->inode_alloc[i]);
-		if (ret)
-			goto out_cleanup;
-	}
+	/*
+	 * FIXME: Should this pre-read all the group descriptors like
+	 * the old code read all the extent maps?
+	 */
 
 	*ret_scan = scan;
 
@@ -311,7 +357,8 @@
 		}
 	}
 
-	ocfs2_free(&scan->extent_buffer);
+	ocfs2_free(&scan->group_buffer);
+	ocfs2_free(&scan->cur_desc);
 	ocfs2_free(&scan->inode_alloc);
 	ocfs2_free(&scan);
 
@@ -352,7 +399,7 @@
 	}
 	filename = argv[1];
 
-	ret = ocfs2_open(filename, OCFS2_FLAG_RO, 0, 0, &fs);
+	ret = ocfs2_open(filename, OCFS2_FLAG_RO|OCFS2_FLAG_BUFFERED, 0, 0, &fs);
 	if (ret) {
 		com_err(argv[0], ret,
 			"while opening file \"%s\"", filename);

Modified: trunk/libocfs2/ocfs2_err.et.in
===================================================================
--- trunk/libocfs2/ocfs2_err.et.in	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/libocfs2/ocfs2_err.et.in	2004-10-02 01:22:53 UTC (rev 309)
@@ -86,4 +86,13 @@
 ec	OCFS2_ET_INTERNAL_FAILURE,
 	"Internal logic faliure"
 
+ec	OCFS2_ET_BAD_GROUP_DESC_MAGIC,
+	"Bad magic number in group descriptor"
+
+ec	OCFS2_ET_CORRUPT_GROUP_DESC,
+	"Group descriptor is corrupt"
+
+ec	OCFS2_ET_CORRUPT_CHAIN,
+	"Chain allocator is corrupt"
+
 	end

Modified: trunk/mkfs.ocfs2/Makefile
===================================================================
--- trunk/mkfs.ocfs2/Makefile	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/mkfs.ocfs2/Makefile	2004-10-02 01:22:53 UTC (rev 309)
@@ -17,7 +17,7 @@
 LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
 
 INCLUDES = $(LIBOCFS2_CFLAGS)
-DEFINES = -DOCFS2_FLAT_INCLUDES
+DEFINES = -DOCFS2_FLAT_INCLUDES -DVERSION=\"$(VERSION)\"
 
 OPTIMIZE = -O2
 
@@ -35,15 +35,14 @@
 
 CFLAGS += $(OPTIMIZE)
 
-VERSION_FILES = mkfs.c
-VERSION_SRC = mkfs.c
-VERSION_PREFIX = OCFS2
+CFILES = mkfs.c
+OBJS = $(subst .c,.o,$(CFILES))
 
 MANS = mkfs.ocfs2.8
 
-DIST_FILES = $(VERSION_FILES) $(VERSION_SRC) mkfs.ocfs2.8.in
+DIST_FILES = $(CFILES) mkfs.ocfs2.8.in
 
-mkfs.ocfs2: mkfs.o
+mkfs.ocfs2: $(OBJS)
 	$(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
 
 readdir: readdir.o

Modified: trunk/mkfs.ocfs2/mkfs.c
===================================================================
--- trunk/mkfs.ocfs2/mkfs.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/mkfs.ocfs2/mkfs.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -79,8 +79,6 @@
 #define AUTOCONF_BLOCKS(i,min)  ((2+4) + (i<min ? min : i))
 #define NUM_LOCAL_SYSTEM_FILES  6
 
-#define MAGIC_SUPERBLOCK_BLOCK_NUMBER  2
-
 #define OCFS2_OS_LINUX           0
 #define OCFS2_OS_HURD            1
 #define OCFS2_OS_MASIX           2
@@ -107,6 +105,7 @@
 	SFI_BITMAP,
 	SFI_LOCAL_ALLOC,
 	SFI_DLM,
+	SFI_CHAIN,
 	SFI_OTHER
 };
 
@@ -125,14 +124,26 @@
 	uint32_t total_bits;
 };
 
+typedef struct _AllocGroup AllocGroup;
 typedef struct _SystemFileDiskRecord SystemFileDiskRecord;
 
+struct _AllocGroup {
+	char *name;
+	ocfs2_group_desc *gd;
+	SystemFileDiskRecord *alloc_inode;
+};
+
+
 struct _SystemFileDiskRecord {
 	uint64_t fe_off;
+        uint16_t suballoc_bit;
 	uint64_t extent_off;
 	uint64_t extent_len;
 	uint64_t file_size;
 
+	uint64_t chain_off;
+	AllocGroup *group;
+
 	struct BitInfo bi;
 
 	int flags;
@@ -201,13 +212,14 @@
 	char *vol_label;
 	char *device_name;
 	char *uuid;
+	uint32_t vol_generation;
 
 	int fd;
 
 	time_t format_time;
 
 	AllocBitmap *global_bm;
-	AllocBitmap *system_bm;
+	AllocGroup *system_group;
 };
 
 
@@ -229,7 +241,7 @@
 				   uint64_t *num);
 static int alloc_from_bitmap(State *s, uint64_t num_bits, AllocBitmap *bitmap,
 			     uint64_t *start, uint64_t *num);
-static uint64_t alloc_inode(State *s, int num_blocks);
+static uint64_t alloc_inode(State *s, uint16_t *suballoc_bit);
 static DirData *alloc_directory(State *s);
 static void add_entry_to_directory(State *s, DirData *dir, char *name,
 				   uint64_t byte_off, uint8_t type);
@@ -243,31 +255,36 @@
 static void write_metadata(State *s, SystemFileDiskRecord *rec, void *src);
 static void write_bitmap_data(State *s, AllocBitmap *bitmap);
 static void write_directory_data(State *s, DirData *dir);
-static void format_leading_space(State *s, uint64_t start);
+static void write_group_data(State *s, AllocGroup *group);
+static void format_leading_space(State *s);
 static void replacement_journal_create(State *s, uint64_t journal_off);
 static void open_device(State *s);
 static void close_device(State *s);
 static int initial_nodes_for_volume(uint64_t size);
 static void generate_uuid(State *s);
+static void create_generation(State *s);
 static void write_autoconfig_header(State *s, SystemFileDiskRecord *rec);
 static void init_record(State *s, SystemFileDiskRecord *rec, int type, int dir);
 static void print_state(State *s);
+static int ocfs2_clusters_per_group(int block_size,
+				    int cluster_size_bits);
+static AllocGroup * initialize_alloc_group(State *s, char *name,
+					   SystemFileDiskRecord *alloc_inode,
+					   uint64_t blkno,
+					   uint16_t chain, uint16_t cpg,
+					   uint16_t bpc);
 
-
 extern char *optarg;
 extern int optind, opterr, optopt;
 
 SystemFileInfo system_files[] = {
 	{ "bad_blocks", SFI_OTHER, 1, 0 },
-	{ "global_inode_alloc", SFI_OTHER, 1, 0 },
-	{ "global_inode_alloc_bitmap", SFI_BITMAP, 1, 0 },
+	{ "global_inode_alloc", SFI_CHAIN, 1, 0 },
 	{ "dlm", SFI_DLM, 1, 0 },
 	{ "global_bitmap", SFI_BITMAP, 1, 0 },
 	{ "orphan_dir", SFI_OTHER, 1, 1 },
-	{ "extent_alloc:%04d", SFI_OTHER, 0, 0 },
-	{ "extent_alloc_bitmap:%04d", SFI_BITMAP, 0, 0 },
-	{ "inode_alloc:%04d", SFI_OTHER, 0, 0 },
-	{ "inode_alloc_bitmap:%04d", SFI_BITMAP, 0, 0 },
+	{ "extent_alloc:%04d", SFI_CHAIN, 0, 0 },
+	{ "inode_alloc:%04d", SFI_CHAIN, 0, 0 },
 	{ "journal:%04d", SFI_JOURNAL, 0, 0 },
 	{ "local_alloc:%04d", SFI_LOCAL_ALLOC, 0, 0 }
 };
@@ -278,6 +295,7 @@
 	State *s;
 	SystemFileDiskRecord *record[NUM_SYSTEM_INODES];
 	SystemFileDiskRecord global_alloc_rec;
+	SystemFileDiskRecord crap_rec;
 	SystemFileDiskRecord superblock_rec;
 	SystemFileDiskRecord root_dir_rec;
 	SystemFileDiskRecord system_dir_rec;
@@ -287,8 +305,7 @@
 	DirData *system_dir;
 	uint32_t need;
 	uint64_t allocated;
-	uint64_t leading_space;
-	SystemFileDiskRecord *tmprec, *tmprec2;
+	SystemFileDiskRecord *tmprec;
 	char fname[SYSTEM_FILE_NAME_MAX];
 
 	setbuf(stdout, NULL);
@@ -304,6 +321,8 @@
 
 	generate_uuid (s);
 
+	create_generation(s);
+
 	print_state (s);
 
 	init_record(s, &global_alloc_rec, SFI_OTHER, 0);
@@ -348,52 +367,54 @@
 					  "global bitmap", tmprec,
 					  &global_alloc_rec);
 
+	/*
+	 * Set all bits up to and including the superblock.
+	 */
+	alloc_bytes_from_bitmap(s, (OCFS2_SUPER_BLOCK_BLKNO + 1) << s->blocksize_bits,
+				s->global_bm, &(crap_rec.extent_off),
+				&(crap_rec.extent_len));
+
+	/*
+	 * Alloc a placeholder for the future global chain allocator
+	 */
+	alloc_from_bitmap(s, 1, s->global_bm, &(crap_rec.extent_off),
+                          &(crap_rec.extent_len));
+
+	/*
+	 * Now allocate the global inode alloc group
+	 */
 	tmprec = &(record[GLOBAL_INODE_ALLOC_SYSTEM_INODE][0]);
-	tmprec2 = &(record[GLOBAL_INODE_ALLOC_BITMAP_SYSTEM_INODE][0]);
+
 	need = blocks_needed(s);
+	alloc_bytes_from_bitmap(s, need << s->blocksize_bits,
+                                s->global_bm,
+                                &(crap_rec.extent_off),
+                                &(crap_rec.extent_len));
 
-	alloc_bytes_from_bitmap (s, need << s->blocksize_bits, s->global_bm,
-				 &(tmprec->extent_off), &(tmprec->extent_len));
+	s->system_group =
+		initialize_alloc_group(s, "system inode group", tmprec,
+				       crap_rec.extent_off >> s->blocksize_bits,
+				       0,
+                                       crap_rec.extent_len >> s->cluster_size_bits,
+				       s->cluster_size / s->blocksize);
 
-	need = ((((need + 7) >> 3) + s->cluster_size - 1) >> s->cluster_size_bits) << s->cluster_size_bits;
-	alloc_bytes_from_bitmap (s, need, s->global_bm, &(tmprec2->extent_off),
-	                         &(tmprec2->extent_len));
+	tmprec->group = s->system_group;
+	tmprec->chain_off =
+		tmprec->group->gd->bg_blkno << s->blocksize_bits;
 
-	s->system_bm =
-		initialize_bitmap(s, tmprec->extent_len >> s->blocksize_bits,
-				  s->blocksize_bits, "system inode bitmap",
-				  tmprec2, tmprec);
-
 	if (!s->quiet)
 		printf("done\n");
 
 	if (!s->quiet)
 		printf("Writing superblock: ");
 
-	leading_space = alloc_inode(s, LEADING_SPACE_BLOCKS);
-	if (leading_space != 0ULL) {
-		com_err(s->progname, 0,
-			"Leading space blocks start at byte %"PRIu64", "
-			"must start at 0", leading_space);
-		exit(1);
-	}
+	superblock_rec.fe_off = (uint64_t)OCFS2_SUPER_BLOCK_BLKNO << s->blocksize_bits;
 
-	superblock_rec.fe_off = alloc_inode(s, SUPERBLOCK_BLOCKS);
-	if (superblock_rec.fe_off != (__u64)MAGIC_SUPERBLOCK_BLOCK_NUMBER << s->blocksize_bits) {
-		com_err(s->progname, 0,
-			"Superblock starts at byte %"PRIu64", "
-			"must start at %"PRIu64"",
-			superblock_rec.fe_off,
-			(uint64_t)MAGIC_SUPERBLOCK_BLOCK_NUMBER << 
-			s->blocksize_bits);
-		exit(1);
-	}
-
 	alloc_from_bitmap (s, 1, s->global_bm,
 			   &root_dir_rec.extent_off,
 			   &root_dir_rec.extent_len);
 
-	root_dir_rec.fe_off = alloc_inode(s, 1);
+	root_dir_rec.fe_off = alloc_inode(s, &root_dir_rec.suballoc_bit);
 	root_dir->record = &root_dir_rec;
 
 	add_entry_to_directory(s, root_dir, ".", root_dir_rec.fe_off, OCFS2_FT_DIR);
@@ -401,7 +422,7 @@
 
 	need = system_dir_blocks_needed(s);
 	alloc_from_bitmap (s, need, s->global_bm, &system_dir_rec.extent_off, &system_dir_rec.extent_len);
-	system_dir_rec.fe_off = alloc_inode(s, 1);
+	system_dir_rec.fe_off = alloc_inode(s, &system_dir_rec.suballoc_bit);
 	system_dir->record = &system_dir_rec;
 	add_entry_to_directory(s, system_dir, ".", system_dir_rec.fe_off, OCFS2_FT_DIR);
 	add_entry_to_directory(s, system_dir, "..", system_dir_rec.fe_off, OCFS2_FT_DIR);
@@ -410,7 +431,7 @@
 		num = (system_files[i].global) ? 1 : s->initial_nodes;
 
 		for (j = 0; j < num; j++) {
-			record[i][j].fe_off = alloc_inode(s, 1);
+			record[i][j].fe_off = alloc_inode(s, &(record[i][j].suballoc_bit));
 			sprintf(fname, system_files[i].name, j);
 			add_entry_to_directory(s, system_dir, fname,
 					       record[i][j].fe_off,
@@ -436,7 +457,7 @@
 	alloc_bytes_from_bitmap(s, tmprec->extent_len, s->global_bm,
 				&(tmprec->extent_off), &allocated);
 
-	format_leading_space(s, leading_space);
+	format_leading_space(s);
 	format_superblock(s, &superblock_rec, &root_dir_rec, &system_dir_rec);
 
 	if (!s->quiet)
@@ -466,7 +487,7 @@
 	}
 
 	write_bitmap_data(s, s->global_bm);
-	write_bitmap_data(s, s->system_bm);
+	write_group_data(s, s->system_group);
 
 	write_directory_data(s, root_dir);
 	write_directory_data(s, system_dir);
@@ -720,8 +741,7 @@
 static void
 version(const char *progname)
 {
-	fprintf(stderr, "%s %s %s (build %s)\n", progname,
-		OCFS2_BUILD_VERSION, OCFS2_BUILD_DATE, OCFS2_BUILD_MD5);
+	fprintf(stderr, "%s %s\n", progname, VERSION);
 }
 
 static void
@@ -857,6 +877,42 @@
 	}
 }
 
+static AllocGroup *
+initialize_alloc_group(State *s, char *name,
+		       SystemFileDiskRecord *alloc_inode,
+		       uint64_t blkno, uint16_t chain,
+		       uint16_t cpg, uint16_t bpc)
+{
+	AllocGroup *group;
+
+	group = do_malloc(s, sizeof(AllocGroup));
+	memset(group, 0, sizeof(AllocGroup));
+
+	group->gd = do_malloc(s, s->blocksize);
+	memset(group->gd, 0, s->blocksize);
+
+	strcpy(group->gd->bg_signature, OCFS2_GROUP_DESC_SIGNATURE);
+	group->gd->bg_generation = cpu_to_le32(s->vol_generation);
+	group->gd->bg_size = (uint32_t)ocfs2_group_bitmap_size(s->blocksize);
+	group->gd->bg_bits = cpg * bpc;
+	group->gd->bg_chain = chain;
+	group->gd->bg_parent_dinode = alloc_inode->fe_off;
+	group->gd->bg_blkno = blkno;
+
+	/* First bit set to account for the descriptor block */
+	ocfs2_set_bit(0, group->gd->bg_bitmap);
+	group->gd->bg_free_bits_count = group->gd->bg_bits - 1;
+
+	alloc_inode->bi.total_bits = group->gd->bg_bits;
+	alloc_inode->bi.used_bits = alloc_inode->bi.total_bits -
+		group->gd->bg_free_bits_count;
+	group->alloc_inode = alloc_inode;
+
+	group->name = strdup(name);
+
+	return group;
+}
+
 static AllocBitmap *
 initialize_bitmap(State *s, uint32_t bits, uint32_t unit_bits,
 		  const char *name, SystemFileDiskRecord *bm_record,
@@ -990,14 +1046,54 @@
 	return 0;
 }
 
+static int alloc_from_group(State *s, uint16_t count,
+			    AllocGroup *group, uint64_t *start_blkno,
+			    uint16_t *num_bits)
+{
+	uint16_t start_bit, end_bit;
+
+	start_bit = ocfs2_find_first_bit_clear(group->gd->bg_bitmap,
+					       group->gd->bg_bits);
+
+	while (start_bit < group->gd->bg_bits) {
+		end_bit = ocfs2_find_next_bit_set(group->gd->bg_bitmap,
+						  group->gd->bg_bits,
+						  start_bit);
+		if ((end_bit - start_bit) >= count) {
+			*num_bits = count;
+			for (*num_bits = 0; *num_bits < count; *num_bits += 1) {
+				ocfs2_set_bit(start_bit + *num_bits,
+					      group->gd->bg_bitmap);
+			}
+			group->gd->bg_free_bits_count -= *num_bits;
+			group->alloc_inode->bi.used_bits += *num_bits;
+			*start_blkno = group->gd->bg_blkno + start_bit;
+			return 0;
+		}
+		start_bit = end_bit;
+	}
+
+	com_err(s->progname, 0,
+		"Could not allocate %"PRIu16" bits from %s alloc group",
+		count, group->name);
+	exit(1);
+
+	return 1;
+}
+
 static uint64_t
-alloc_inode(State *s, int num_blocks)
+alloc_inode(State *s, uint16_t *suballoc_bit)
 {
-	uint64_t ret, num;
+	uint64_t ret;
+	uint16_t num;
 
-	alloc_from_bitmap(s, num_blocks, s->system_bm, &ret, &num);
+	alloc_from_group(s, 1, s->system_group,
+			 &ret, &num);
 
-	return ret;
+        *suballoc_bit = (int)(ret - s->system_group->gd->bg_blkno);
+
+        /* Did I mention I hate this code? */
+	return (ret << s->blocksize_bits);
 }
 
 static DirData *
@@ -1144,7 +1240,7 @@
 
 	strcpy(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE);
 	di->i_suballoc_node = cpu_to_le16((__u16)-1);
-	di->i_suballoc_blkno = cpu_to_le64(super_off >> s->blocksize_bits);
+	di->i_suballoc_bit = cpu_to_le16((__u16)-1);
 
 	di->i_atime = 0;
 	di->i_ctime = cpu_to_le64(s->format_time);
@@ -1152,6 +1248,7 @@
 	di->i_blkno = cpu_to_le64(super_off >> s->blocksize_bits);
 	di->i_flags = cpu_to_le32(OCFS2_VALID_FL | OCFS2_SYSTEM_FL |
 				  OCFS2_SUPER_BLOCK_FL);
+	di->i_clusters = s->volume_size_in_clusters;
 	di->id2.i_super.s_major_rev_level = cpu_to_le16(OCFS2_MAJOR_REV_LEVEL);
 	di->id2.i_super.s_minor_rev_level = cpu_to_le16(OCFS2_MINOR_REV_LEVEL);
 	di->id2.i_super.s_root_blkno = cpu_to_le64(root_rec->fe_off >> s->blocksize_bits);
@@ -1174,6 +1271,28 @@
 	free(di);
 }
 
+static int 
+ocfs2_clusters_per_group(int block_size, int cluster_size_bits)
+{
+	int bytes;
+
+	switch (block_size) {
+	case (4096):
+	case (2048):
+		bytes = 4 * ONE_MEGA_BYTE;
+		break;
+	case (1024):
+		bytes = 2 * ONE_MEGA_BYTE;
+		break;
+	case (512):
+	default:
+		bytes = ONE_MEGA_BYTE;
+		break;
+	}
+
+	return(bytes >> cluster_size_bits);
+}
+
 static void
 format_file(State *s, SystemFileDiskRecord *rec)
 {
@@ -1189,9 +1308,9 @@
 	memset(di, 0, s->blocksize);
 
 	strcpy(di->i_signature, OCFS2_INODE_SIGNATURE);
-	di->i_generation = 0;
+	di->i_generation = cpu_to_le32(s->vol_generation);
 	di->i_suballoc_node = cpu_to_le16(-1);
-	di->i_suballoc_blkno = cpu_to_le64(rec->fe_off >> s->blocksize_bits);
+        di->i_suballoc_bit = cpu_to_le16(rec->suballoc_bit);
 	di->i_blkno = cpu_to_le64(rec->fe_off >> s->blocksize_bits);
 	di->i_uid = 0;
 	di->i_gid = 0;
@@ -1214,6 +1333,35 @@
 		di->id1.bitmap1.i_total = cpu_to_le32(rec->bi.total_bits);
 	}
 
+	if (rec->flags & OCFS2_CHAIN_FL) {
+		di->id2.i_chain.cl_count = 
+			cpu_to_le16(ocfs2_chain_recs_per_inode(s->blocksize));
+		di->id2.i_chain.cl_cpg = 
+			cpu_to_le16(ocfs2_clusters_per_group(s->blocksize, 
+						 s->cluster_size_bits));
+		di->id2.i_chain.cl_bpc = 
+			cpu_to_le16(s->cluster_size / s->blocksize);
+		di->id2.i_chain.cl_next_free_rec = 0;
+
+		if (rec->chain_off) {
+			di->id2.i_chain.cl_next_free_rec =
+				cpu_to_le16(1);
+			di->id2.i_chain.cl_recs[0].c_free =
+				cpu_to_le16(rec->group->gd->bg_free_bits_count);
+			di->id2.i_chain.cl_recs[0].c_total =
+				cpu_to_le16(rec->group->gd->bg_bits);
+			di->id2.i_chain.cl_recs[0].c_blkno =
+				cpu_to_le64(rec->chain_off >> s->blocksize_bits);
+                        di->id2.i_chain.cl_cpg =
+                            cpu_to_le16(rec->group->gd->bg_bits /
+                                        le16_to_cpu(di->id2.i_chain.cl_bpc));
+			di->i_clusters =
+                            cpu_to_le64(di->id2.i_chain.cl_cpg);
+			di->i_size =
+                            cpu_to_le64(di->i_clusters << s->cluster_size_bits);
+		}
+		goto write_out;
+	}
 	di->id2.i_list.l_count =
 		cpu_to_le16(ocfs2_extent_recs_per_inode(s->blocksize));
 	di->id2.i_list.l_next_free_rec = 0;
@@ -1254,13 +1402,20 @@
 }
 
 static void
+write_group_data(State *s, AllocGroup *group)
+{
+	do_pwrite(s, group->gd, s->blocksize,
+		  group->gd->bg_blkno << s->blocksize_bits);
+}
+
+static void
 write_directory_data(State *s, DirData *dir)
 {
 	write_metadata(s, dir->record, dir->buf);
 }
 
 static void
-format_leading_space(State *s, uint64_t start)
+format_leading_space(State *s)
 {
 	int num_blocks = 2, size;
 	ocfs1_vol_disk_hdr *hdr;
@@ -1282,7 +1437,7 @@
 	strcpy(lbl->label, "this is an ocfs2 volume");
 	strcpy(lbl->cluster_name, "this is an ocfs2 volume");
 
-	do_pwrite(s, buf, size, start);
+	do_pwrite(s, buf, size, 0);
 	free(buf);
 }
 
@@ -1384,6 +1539,27 @@
 	close(randfd);
 }
 
+static void create_generation(State *s)
+{
+	int randfd = 0;
+	int readlen = sizeof(s->vol_generation);
+
+	if ((randfd = open("/dev/urandom", O_RDONLY)) == -1) {
+		com_err(s->progname, 0,
+			"Error opening /dev/urandom: %s", strerror(errno));
+		exit(1);
+	}
+
+	if (read(randfd, &s->vol_generation, readlen) != readlen) {
+		com_err(s->progname, 0,
+			"Error reading from /dev/urandom: %s",
+			strerror(errno));
+		exit(1);
+	}
+
+	close(randfd);
+}
+
 static void
 write_autoconfig_header(State *s, SystemFileDiskRecord *rec)
 {
@@ -1428,6 +1604,9 @@
 	case SFI_DLM:
 		rec->flags |= OCFS2_DLM_FL;
 		break;
+	case SFI_CHAIN:
+		rec->flags |= (OCFS2_BITMAP_FL|OCFS2_CHAIN_FL);
+		break;
 	case SFI_OTHER:
 		break;
 	}

Modified: trunk/mounted.ocfs2/Makefile
===================================================================
--- trunk/mounted.ocfs2/Makefile	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/mounted.ocfs2/Makefile	2004-10-02 01:22:53 UTC (rev 309)
@@ -30,15 +30,14 @@
 
 CFLAGS += $(OPTIMIZE)
 
-VERSION_FILES = mounted.c
-VERSION_SRC = mounted.c
-VERSION_PREFIX = OCFS2
+CFILES = mounted.c
+OBJS = $(subst .c,.o,$(CFILES))
 
 #MANS = fsck.ocfs2.8
 
-DIST_FILES = $(VERSION_FILES) $(VERSION_SRC)
+DIST_FILES = $(CFILES)
 
-mounted.ocfs2: mounted.o
-	$(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS) $(VERMAGIC)
+mounted.ocfs2: $(OBJS)
+	$(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
 
 include $(TOPDIR)/Postamble.make

Modified: trunk/ocfs2cdsl/Makefile
===================================================================
--- trunk/ocfs2cdsl/Makefile	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/ocfs2cdsl/Makefile	2004-10-02 01:22:53 UTC (rev 309)
@@ -12,24 +12,23 @@
 
 SBIN_PROGRAMS = ocfs2cdsl
 
-DEFINES = -DG_DISABLE_DEPRECATED
+DEFINES = -DG_DISABLE_DEPRECATED -DVERSION=\"$(VERSION)\"
 INCLUDES = $(GLIB_CFLAGS)
 
 OPTIMIZE = -g -O2
 
 CFLAGS += $(OPTIMIZE)
 
-VERSION_FILES = ocfs2cdsl.c
-VERSION_SRC = ocfs2cdsl.c
-VERSION_PREFIX = OCFS2
+CFILES = ocfs2cdsl.c
+OBJS = $(subst .c,.o,$(CFILES))
 
 DIST_RULES = dist-incdir
 
 #MANS = ocfs2cdsl.8
 
-DIST_FILES = $(VERSION_FILES) $(VERSION_SRC) ocfs2cdsl.c #ocfs2cdsl.8.in
+DIST_FILES = $(CFILES) #ocfs2cdsl.8.in
 
-ocfs2cdsl: ocfs2cdsl.o
+ocfs2cdsl: $(OBJS)
 	$(LINK) $(GLIB_LIBS)
 
 include $(TOPDIR)/Postamble.make

Modified: trunk/ocfs2cdsl/ocfs2cdsl.c
===================================================================
--- trunk/ocfs2cdsl/ocfs2cdsl.c	2004-10-01 22:28:00 UTC (rev 308)
+++ trunk/ocfs2cdsl/ocfs2cdsl.c	2004-10-02 01:22:53 UTC (rev 309)
@@ -365,8 +365,7 @@
 static void
 version(const char *progname)
 {
-	fprintf(stderr, "%s %s %s (build %s)\n", progname,
-		OCFS2_BUILD_VERSION, OCFS2_BUILD_DATE, OCFS2_BUILD_MD5);
+	fprintf(stderr, "%s %s\n", progname, VERSION);
 }
 
 static char *



More information about the Ocfs2-tools-commits mailing list