[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