[Ocfs-tools-commits]
jlbec commits r194 - in trunk/ocfs2: . extras libocfs2
libocfs2/include
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Mon Aug 9 17:40:28 CDT 2004
Author: jlbec
Date: 2004-08-09 16:40:25 -0500 (Mon, 09 Aug 2004)
New Revision: 194
Added:
trunk/ocfs2/extras/
trunk/ocfs2/extras/Makefile
trunk/ocfs2/extras/find_hardlinks.c
Modified:
trunk/ocfs2/Makefile
trunk/ocfs2/libocfs2/bitmap.c
trunk/ocfs2/libocfs2/include/
trunk/ocfs2/libocfs2/include/bitmap.h
trunk/ocfs2/libocfs2/include/ocfs2.h
Log:
Woo! find_hardlinks
Modified: trunk/ocfs2/Makefile
===================================================================
--- trunk/ocfs2/Makefile 2004-08-09 21:11:06 UTC (rev 193)
+++ trunk/ocfs2/Makefile 2004-08-09 21:40:25 UTC (rev 194)
@@ -2,7 +2,7 @@
include $(TOPDIR)/Preamble.make
-SUBDIRS = libocfs2 mkfs.ocfs2
+SUBDIRS = libocfs2 mkfs.ocfs2 extras
ifdef DEBUGOCFS2
SUBDIRS += debugfs.ocfs2
Property changes on: trunk/ocfs2/extras
___________________________________________________________________
Name: svn:ignore
+ .*.sw?
find_hardlinks
Copied: trunk/ocfs2/extras/Makefile (from rev 192, trunk/ocfs2/fsck.ocfs2/Makefile)
===================================================================
--- trunk/ocfs2/fsck.ocfs2/Makefile 2004-08-06 19:53:49 UTC (rev 192)
+++ trunk/ocfs2/extras/Makefile 2004-08-09 21:40:25 UTC (rev 194)
@@ -0,0 +1,45 @@
+TOPDIR = ../..
+
+include $(TOPDIR)/Preamble.make
+
+WARNINGS = -Wall -Wstrict-prototypes -Wno-format -Wmissing-prototypes \
+ -Wmissing-declarations
+
+ifdef OCFS_DEBUG
+OPTS = -g
+endif
+
+CFLAGS = $(OPTS) -fno-strict-aliasing $(WARNINGS)
+
+UNINST_PROGRAMS = find_hardlinks
+
+INCLUDES = -I../libocfs2/include
+
+OPTIMIZE = -O2
+
+ifeq ($(OCFS_PROCESSOR),x86_64)
+ CFLAGS += -m64
+endif
+ifeq ($(OCFS_PROCESSOR),ia64)
+endif
+ifeq ($(OCFS_PROCESSOR),i686)
+ DEFINES += -D__ILP32__
+endif
+
+DEFINES += -DOCFS2_FLAT_INCLUDES
+
+CFLAGS += $(OPTIMIZE)
+
+FIND_HARDLINKS_CFILES = \
+ find_hardlinks.c
+
+DIST_FILES = $(FIND_HARDLINKS_CFILES)
+FIND_HARDLINKS_OBJS = $(subst .c,.o,$(FIND_HARDLINKS_CFILES))
+
+LIBOCFS2 = ../libocfs2/libocfs2.a
+LIBS = $(LIBOCFS2) $(COM_ERR_LIBS)
+
+find_hardlinks: $(FIND_HARDLINKS_OBJS) $(LIBS)
+ $(LINK)
+
+include $(TOPDIR)/Postamble.make
Added: trunk/ocfs2/extras/find_hardlinks.c
===================================================================
--- trunk/ocfs2/extras/find_hardlinks.c 2004-08-09 21:11:06 UTC (rev 193)
+++ trunk/ocfs2/extras/find_hardlinks.c 2004-08-09 21:40:25 UTC (rev 194)
@@ -0,0 +1,270 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * find_hardlinks.c
+ *
+ * Simple tool to iterate the directories and find hardlinks.
+ *
+ * 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
+ *
+ * This code is a port of e2fsprogs/lib/ext2fs/dir_iterate.c
+ * Copyright (C) 1993, 1994, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ */
+
+#define _XOPEN_SOURCE 600 /* Triggers magic in features.h */
+#define _LARGEFILE64_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "ocfs2.h"
+
+static void print_usage(void)
+{
+ fprintf(stderr,
+ "Usage: find_hardlinks <filename> [-q]\n");
+}
+
+struct walk_path {
+ char *argv0;
+ ocfs2_filesys *fs;
+ char *path;
+ int quiet;
+ int has_dups;
+ int check_dups;
+ ocfs2_bitmap *inode_map;
+ ocfs2_bitmap *dup_map;
+};
+
+static int walk_tree_func(struct ocfs2_dir_entry *dentry,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data)
+{
+ errcode_t ret;
+ int len, oldval;
+ int reti = 0;
+ char *old_path, *path;
+ struct walk_path *wp = priv_data;
+
+ if (!strncmp(dentry->name, ".", dentry->name_len) ||
+ !strncmp(dentry->name, "..", dentry->name_len))
+ return 0;
+
+ len = strlen(wp->path);
+
+ if (len + dentry->name_len > 4095) {
+ fprintf(stderr, "name is too long in %s\n", wp->path);
+ return OCFS2_DIRENT_ABORT;
+ }
+
+ ret = ocfs2_malloc0(4096, &path);
+ if (ret) {
+ com_err(wp->argv0, ret,
+ "while allocating path memory in %s\n",
+ wp->path);
+ return OCFS2_DIRENT_ABORT;
+ }
+
+ memcpy(path, wp->path, len);
+ memcpy(path + len, dentry->name, dentry->name_len);
+ if (dentry->file_type == OCFS2_FT_DIR)
+ path[len + dentry->name_len] = '/';
+
+ if (wp->check_dups) {
+ ret = ocfs2_bitmap_test(wp->dup_map, dentry->inode,
+ &oldval);
+ if (oldval) {
+ fprintf(stdout, "Dup! % 20llu %s\n", dentry->inode, path);
+ }
+ goto out;
+ }
+
+ oldval = 0;
+ ret = ocfs2_bitmap_set(wp->inode_map, dentry->inode, &oldval);
+ if (ret) {
+ com_err(wp->argv0, ret,
+ "while setting bitmap bit %llu\n",
+ dentry->inode);
+ reti = OCFS2_DIRENT_ABORT;
+ goto out;
+ }
+
+ if (oldval) {
+ wp->has_dups = 1;
+ ret = ocfs2_bitmap_set(wp->dup_map, dentry->inode,
+ NULL);
+ if (ret) {
+ com_err(wp->argv0, ret,
+ "while setting dup bit %llu\n",
+ dentry->inode);
+ reti = OCFS2_DIRENT_ABORT;
+ goto out;
+ }
+ }
+
+ if (!wp->quiet)
+ fprintf(stdout, "% 20llu %s\n", dentry->inode, path);
+
+ if (dentry->file_type == OCFS2_FT_DIR) {
+ old_path = wp->path;
+ wp->path = path;
+ ret = ocfs2_dir_iterate(wp->fs, dentry->inode, 0, NULL,
+ walk_tree_func, wp);
+ if (ret) {
+ com_err(wp->argv0, ret,
+ "while walking %s", wp->path);
+ reti = OCFS2_DIRENT_ABORT;
+ }
+ wp->path = old_path;
+ }
+
+out:
+ ocfs2_free(&path);
+
+ return reti;
+}
+
+
+
+extern int opterr, optind;
+extern char *optarg;
+
+int main(int argc, char *argv[])
+{
+ errcode_t ret;
+ uint64_t blkno;
+ char *filename;
+ ocfs2_filesys *fs;
+ struct walk_path wp;
+
+ blkno = OCFS2_SUPER_BLOCK_BLKNO;
+
+ initialize_ocfs_error_table();
+
+ wp.argv0 = argv[0];
+ wp.quiet = 0;
+ wp.has_dups = 0;
+ wp.check_dups = 0;
+ if (argc < 2) {
+ fprintf(stderr, "Missing filename\n");
+ print_usage();
+ return 1;
+ }
+ filename = argv[1];
+
+ if (argc > 2) {
+ if (!strcmp(argv[2], "-q"))
+ wp.quiet = 1;
+ }
+
+ ret = ocfs2_open(filename, OCFS2_FLAG_RO, 0, 0, &fs);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while opening file \"%s\"", filename);
+ goto out;
+ }
+ wp.fs = fs;
+
+ ret = ocfs2_block_bitmap_new(fs, "Inode bitmap", &wp.inode_map);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while creating the inode bitmap");
+ goto out_close;
+ }
+
+ ret = ocfs2_block_bitmap_new(fs, "Duplicate inode bitmap",
+ &wp.dup_map);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while creating the duplicate inode bitmap");
+ goto out_close;
+ }
+
+ ocfs2_bitmap_set(wp.inode_map,
+ OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno,
+ NULL);
+ ocfs2_bitmap_set(wp.inode_map,
+ OCFS2_RAW_SB(fs->fs_super)->s_root_blkno,
+ NULL);
+
+ fprintf(stdout, "Walking system directory...\n");
+ wp.path = "<system_dir>/";
+ ret = ocfs2_dir_iterate(fs,
+ OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno,
+ 0, NULL, walk_tree_func, &wp);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while walking sysdm dir inode %llu on \"%s\"\n",
+ blkno, filename);
+ goto out_close;
+ }
+ wp.path = "/";
+ fprintf(stdout, "Walking root directory...\n");
+ ret = ocfs2_dir_iterate(fs,
+ OCFS2_RAW_SB(fs->fs_super)->s_root_blkno,
+ 0, NULL, walk_tree_func, &wp);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while walking root inode %llu on \"%s\"\n",
+ blkno, filename);
+ goto out_close;
+ }
+
+ if (wp.has_dups) {
+ fprintf(stdout, "Hardlinks found\n");
+
+ wp.check_dups = 1;
+ fprintf(stdout, "Scanning system directory for dups...\n");
+ wp.path = "<system_dir>/";
+ ret = ocfs2_dir_iterate(fs,
+ OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno,
+ 0, NULL, walk_tree_func, &wp);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while dup scanning sysdm dir inode %llu on \"%s\"\n",
+ blkno, filename);
+ goto out_close;
+ }
+ wp.path = "/";
+ fprintf(stdout, "Scanning root directory for dups...\n");
+ ret = ocfs2_dir_iterate(fs,
+ OCFS2_RAW_SB(fs->fs_super)->s_root_blkno,
+ 0, NULL, walk_tree_func, &wp);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while dup scanning root inode %llu on \"%s\"\n",
+ blkno, filename);
+ goto out_close;
+ }
+ }
+
+out_close:
+ ret = ocfs2_close(fs);
+ if (ret) {
+ com_err(argv[0], ret,
+ "while closing file \"%s\"", filename);
+ }
+
+out:
+ return 0;
+}
+
Modified: trunk/ocfs2/libocfs2/bitmap.c
===================================================================
--- trunk/ocfs2/libocfs2/bitmap.c 2004-08-09 21:11:06 UTC (rev 193)
+++ trunk/ocfs2/libocfs2/bitmap.c 2004-08-09 21:40:25 UTC (rev 194)
@@ -68,15 +68,20 @@
int *oldval)
{
errcode_t ret;
+ int old_tmp;
if (bitno >= bitmap->b_total_bits)
return OCFS2_ET_INVALID_BIT;
- ret = (*bitmap->b_ops->set_bit)(bitmap, bitno, oldval);
+ ret = (*bitmap->b_ops->set_bit)(bitmap, bitno, &old_tmp);
if (ret)
return ret;
- bitmap->b_set_bits++;
+ if (!old_tmp)
+ bitmap->b_set_bits++;
+ if (oldval)
+ *oldval = old_tmp;
+
return 0;
}
@@ -84,15 +89,20 @@
int *oldval)
{
errcode_t ret;
+ int old_tmp;
if (bitno >= bitmap->b_total_bits)
return OCFS2_ET_INVALID_BIT;
- ret = (*bitmap->b_ops->clear_bit)(bitmap, bitno, oldval);
+ ret = (*bitmap->b_ops->clear_bit)(bitmap, bitno, &old_tmp);
if (ret)
return ret;
- bitmap->b_set_bits--;
+ if (old_tmp)
+ bitmap->b_set_bits--;
+ if (oldval)
+ *oldval = old_tmp;
+
return 0;
}
@@ -121,7 +131,7 @@
*/
errcode_t ocfs2_bitmap_new(ocfs2_filesys *fs,
uint64_t total_bits,
- char *description,
+ const char *description,
struct ocfs2_bitmap_operations *ops,
void *private_data,
ocfs2_bitmap **ret_bitmap)
@@ -160,7 +170,20 @@
return ret;
}
+static uint64_t ocfs2_bits_to_clusters(ocfs2_bitmap *bitmap,
+ int num_bits)
+{
+ uint64_t bpos;
+ int bpc;
+ uint32_t cpos;
+ bpc = bitmap->b_fs->fs_clustersize * 8;
+ cpos = ((unsigned int)num_bits + (bpc - 1)) / bpc;
+ bpos = (uint64_t)cpos * bpc;
+
+ return bpos;
+}
+
errcode_t ocfs2_bitmap_alloc_cluster(ocfs2_bitmap *bitmap,
uint64_t start_bit,
int total_bits,
@@ -168,24 +191,24 @@
{
errcode_t ret;
struct ocfs2_bitmap_cluster *bc;
- int cl_bits;
- ocfs2_filesys *fs = bitmap->b_fs;
+ uint64_t real_bits;
if (total_bits < 0)
return OCFS2_ET_INVALID_BIT;
+ real_bits = ocfs2_bits_to_clusters(bitmap, total_bits);
+ if (real_bits > INT_MAX)
+ return OCFS2_ET_INVALID_BIT;
+
ret = ocfs2_malloc0(sizeof(struct ocfs2_bitmap_cluster), &bc);
if (ret)
return ret;
- bc->bc_start_bit = start_bit;
- bc->bc_total_bits = total_bits;
+ start_bit &= ~((bitmap->b_fs->fs_clustersize * 8) - 1);
+ bc->bc_start_bit = ocfs2_bits_to_clusters(bitmap, start_bit);
+ bc->bc_total_bits = real_bits;
- cl_bits = OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
- bc->bc_size = (size_t)(((unsigned int)total_bits + 7) / 8);
- bc->bc_size = ((bc->bc_size + (fs->fs_clustersize - 1)) >> cl_bits) << cl_bits;
-
- ret = ocfs2_malloc0(bc->bc_size, &bc->bc_bitmap);
+ ret = ocfs2_malloc0((size_t)real_bits / 8, &bc->bc_bitmap);
if (ret)
ocfs2_free(&bc);
else
@@ -198,7 +221,6 @@
{
if (bc->bc_bitmap)
ocfs2_free(&bc->bc_bitmap);
-
ocfs2_free(&bc);
}
@@ -207,27 +229,70 @@
int total_bits)
{
errcode_t ret;
- ocfs2_filesys *fs = bitmap->b_fs;
- size_t new_size;
- int cl_bits;
+ uint64_t real_bits;
if ((bc->bc_start_bit + total_bits) > bitmap->b_total_bits)
return OCFS2_ET_INVALID_BIT;
- cl_bits = OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
- new_size = (size_t)(((unsigned int)total_bits + 7) / 8);
- new_size = ((new_size + (fs->fs_clustersize - 1)) >> cl_bits) << cl_bits;
+ real_bits = ocfs2_bits_to_clusters(bitmap, total_bits);
+ if (real_bits > INT_MAX)
+ return OCFS2_ET_INVALID_BIT;
- if (new_size > bc->bc_size) {
- ret = ocfs2_realloc0(new_size, &bc->bc_bitmap,
- bc->bc_size);
+ if (real_bits > bc->bc_total_bits) {
+ ret = ocfs2_realloc0((size_t)real_bits / 8,
+ &bc->bc_bitmap,
+ bc->bc_total_bits / 8);
if (ret)
return ret;
- bc->bc_size = new_size;
+ bc->bc_total_bits = (int)real_bits;
}
- bc->bc_total_bits = total_bits;
+ return 0;
+}
+/*
+ * Attempt to merge two clusters. If the merge is successful, 0 will
+ * be returned and prev will be the only valid cluster. Next will
+ * be freed.
+ */
+static errcode_t ocfs2_bitmap_merge_cluster(ocfs2_bitmap *bitmap,
+ struct ocfs2_bitmap_cluster *prev,
+ struct ocfs2_bitmap_cluster *next)
+{
+ errcode_t ret;
+ uint64_t new_bits;
+ int prev_bits;
+
+ if ((prev->bc_start_bit + prev->bc_total_bits) !=
+ 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))
+ return OCFS2_ET_INVALID_BIT;
+
+ new_bits = (uint64_t)(prev->bc_total_bits) +
+ (uint64_t)(next->bc_total_bits);
+ if (new_bits > INT_MAX)
+ return OCFS2_ET_INVALID_BIT;
+
+ prev_bits = prev->bc_total_bits;
+ ret = ocfs2_bitmap_realloc_cluster(bitmap, prev, new_bits);
+ if (ret)
+ return ret;
+
+ memcpy(prev->bc_bitmap + (prev_bits / 8), next->bc_bitmap,
+ next->bc_total_bits / 8);
+
+ list_del(&next->bc_list);
+ ocfs2_bitmap_free_cluster(next);
+
return 0;
}
@@ -237,8 +302,7 @@
struct list_head *pos, *prev;
struct ocfs2_bitmap_cluster *bc_tmp;
- if ((bc->bc_start_bit + bc->bc_total_bits) >
- bitmap->b_total_bits)
+ if (bc->bc_start_bit > bitmap->b_total_bits)
return OCFS2_ET_INVALID_BIT;
prev = &bitmap->b_clusters;
@@ -259,6 +323,18 @@
list_add(&bc->bc_list, prev);
+ if (pos != &bitmap->b_clusters) {
+ bc_tmp = list_entry(pos, struct ocfs2_bitmap_cluster,
+ bc_list);
+ ocfs2_bitmap_merge_cluster(bitmap, bc, bc_tmp);
+ }
+
+ if (prev != &bitmap->b_clusters) {
+ bc_tmp = list_entry(prev, struct ocfs2_bitmap_cluster,
+ bc_list);
+ ocfs2_bitmap_merge_cluster(bitmap, bc_tmp, bc);
+ }
+
return 0;
}
@@ -287,6 +363,9 @@
if (oldval)
*oldval = old_tmp;
+ if (!old_tmp)
+ bc->bc_set_bits++;
+
return 0;
}
@@ -313,6 +392,9 @@
if (oldval)
*oldval = old_tmp;
+ if (old_tmp)
+ bc->bc_set_bits--;
+
return 0;
}
@@ -341,72 +423,191 @@
return OCFS2_ET_INVALID_BIT;
}
-#ifdef DEBUG_EXE
-#include <stdlib.h>
-#include <getopt.h>
-#include <limits.h>
-static uint64_t read_number(const char *num)
+/*
+ * Helper functions for a bitmap with holes in it.
+ * If a bit doesn't have memory allocated for it, we allocate.
+ */
+errcode_t ocfs2_bitmap_set_holes(ocfs2_bitmap *bitmap,
+ uint64_t bitno, int *oldval)
{
- uint64_t val;
- char *ptr;
+ errcode_t ret;
+ struct ocfs2_bitmap_cluster *bc;
- val = strtoull(num, &ptr, 0);
- if (!ptr || *ptr)
+ if (!ocfs2_bitmap_set_generic(bitmap, bitno, oldval))
return 0;
- return val;
+ ret = ocfs2_bitmap_alloc_cluster(bitmap, bitno, 1, &bc);
+ if (ret)
+ return ret;
+
+ ret = ocfs2_bitmap_insert_cluster(bitmap, bc);
+ if (ret)
+ return ret;
+
+ return ocfs2_bitmap_set_generic(bitmap, bitno, oldval);
}
-static void print_usage(void)
+errcode_t ocfs2_bitmap_clear_holes(ocfs2_bitmap *bitmap,
+ uint64_t bitno, int *oldval)
{
- fprintf(stderr, "bitmap [-n <num_bits>] [-a] <filename>\n");
+ errcode_t ret;
+ struct ocfs2_bitmap_cluster *bc;
+
+ if (!ocfs2_bitmap_clear_generic(bitmap, bitno, oldval))
+ return 0;
+
+ ret = ocfs2_bitmap_alloc_cluster(bitmap, bitno, 1, &bc);
+ if (ret)
+ return ret;
+
+ ret = ocfs2_bitmap_insert_cluster(bitmap, bc);
+
+ return ret;
}
-extern int opterr, optind;
-extern char *optarg;
+errcode_t ocfs2_bitmap_test_holes(ocfs2_bitmap *bitmap,
+ uint64_t bitno, int *val)
+{
+ if (ocfs2_bitmap_test_generic(bitmap, bitno, val))
+ *val = 0;
-static struct ocfs2_bitmap_operations generic_ops = {
+ return 0;
+}
+
+static struct ocfs2_bitmap_operations global_cluster_ops = {
.set_bit = ocfs2_bitmap_set_generic,
.clear_bit = ocfs2_bitmap_clear_generic,
.test_bit = ocfs2_bitmap_test_generic
};
-static errcode_t create_bitmap(ocfs2_filesys *fs, int num_bits,
- ocfs2_bitmap **ret_bitmap)
+errcode_t ocfs2_cluster_bitmap_new(ocfs2_filesys *fs,
+ const char *description,
+ ocfs2_bitmap **ret_bitmap)
{
errcode_t ret;
ocfs2_bitmap *bitmap;
+ uint64_t max_bits, num_bits, bitoff, alloc_bits;
struct ocfs2_bitmap_cluster *bc;
+ num_bits = fs->fs_clusters;
ret = ocfs2_bitmap_new(fs,
num_bits,
- "Test bitmap",
- &generic_ops,
+ description ? description :
+ "Generic cluster bitmap",
+ &global_cluster_ops,
NULL,
&bitmap);
if (ret)
return ret;
- ret = ocfs2_bitmap_alloc_cluster(bitmap, 0, num_bits, &bc);
- if (ret) {
- ocfs2_bitmap_free(bitmap);
- return ret;
+ bitoff = 0;
+ max_bits = INT_MAX - (fs->fs_clustersize - 1);
+ while (bitoff < num_bits) {
+ alloc_bits = ocfs2_bits_to_clusters(bitmap,
+ num_bits);
+ if (num_bits > max_bits)
+ alloc_bits = max_bits;
+
+ ret = ocfs2_bitmap_alloc_cluster(bitmap, bitoff,
+ alloc_bits, &bc);
+ if (ret) {
+ ocfs2_bitmap_free(bitmap);
+ return ret;
+ }
+
+ ret = ocfs2_bitmap_insert_cluster(bitmap, bc);
+ if (ret) {
+ ocfs2_bitmap_free_cluster(bc);
+ ocfs2_bitmap_free(bitmap);
+ return ret;
+ }
+
+ bitoff += alloc_bits;
}
- ret = ocfs2_bitmap_insert_cluster(bitmap, bc);
- if (ret) {
- ocfs2_bitmap_free_cluster(bc);
- ocfs2_bitmap_free(bitmap);
- } else
- *ret_bitmap = bitmap;
+ *ret_bitmap = bitmap;
- return ret;
+ return 0;
}
+
+static struct ocfs2_bitmap_operations global_block_ops = {
+ .set_bit = ocfs2_bitmap_set_holes,
+ .clear_bit = ocfs2_bitmap_clear_holes,
+ .test_bit = ocfs2_bitmap_test_holes
+};
+
+errcode_t ocfs2_block_bitmap_new(ocfs2_filesys *fs,
+ const char *description,
+ ocfs2_bitmap **ret_bitmap)
+{
+ errcode_t ret;
+ ocfs2_bitmap *bitmap;
+
+ ret = ocfs2_bitmap_new(fs,
+ fs->fs_blocks,
+ description ? description :
+ "Generic block bitmap",
+ &global_block_ops,
+ NULL,
+ &bitmap);
+ if (ret)
+ return ret;
+
+ *ret_bitmap = bitmap;
+
+ return 0;
+}
+
+
+#ifdef DEBUG_EXE
+#include <stdlib.h>
+#include <getopt.h>
+#include <limits.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, "bitmap [-n <num_bits>] [-a] <filename>\n");
+}
+
+extern int opterr, optind;
+extern char *optarg;
+
+static void dump_clusters(ocfs2_bitmap *bitmap)
+{
+ struct list_head *pos;
+ struct ocfs2_bitmap_cluster *bc;
+
+ fprintf(stdout, "Bitmap \"%s\": total = %llu, set = %llu\n",
+ bitmap->b_description, bitmap->b_total_bits,
+ bitmap->b_set_bits);
+ list_for_each(pos, &bitmap->b_clusters) {
+ bc = list_entry(pos, struct ocfs2_bitmap_cluster,
+ bc_list);
+ fprintf(stdout,
+ "(start: %llu, n: %d, set: %d, cpos: %u)\n",
+ bc->bc_start_bit, bc->bc_total_bits,
+ bc->bc_set_bits, bc->bc_cpos);
+ }
+}
+
static void print_bitmap(ocfs2_bitmap *bitmap)
{
- uint64_t bitno, gap_start;
+ uint64_t bitno;
+ uint64_t gap_start = 0; /* GCC is dumb */
errcode_t ret;
int val, gap;
@@ -527,6 +728,8 @@
}
} else if (!strcmp(cmd, "print")) {
print_bitmap(bitmap);
+ } else if (!strcmp(cmd, "dump")) {
+ dump_clusters(bitmap);
} else if (!strcmp(cmd, "quit")) {
break;
} else {
@@ -541,32 +744,18 @@
errcode_t ret;
int c;
int alloc = 0;
- uint64_t val;
- int num_bits = 4096;
char *filename;
ocfs2_filesys *fs;
ocfs2_bitmap *bitmap;
initialize_ocfs_error_table();
- while ((c = getopt(argc, argv, "s:a")) != EOF) {
+ while ((c = getopt(argc, argv, "a")) != EOF) {
switch (c) {
case 'a':
alloc = 1;
break;
- case 's':
- val = read_number(optarg);
- if (!val || (val > INT_MAX)) {
- fprintf(stderr,
- "Invalid size: %s\n",
- optarg);
- print_usage();
- return 1;
- }
- num_bits = (int)val;
- break;
-
default:
print_usage();
return 1;
@@ -588,7 +777,10 @@
return 1;
}
- ret = create_bitmap(fs, num_bits, &bitmap);
+ if (alloc)
+ ret = ocfs2_block_bitmap_new(fs, "Testing", &bitmap);
+ else
+ ret = ocfs2_cluster_bitmap_new(fs, "Testing", &bitmap);
if (ret) {
com_err(argv[0], ret,
"while creating bitmap");
Property changes on: trunk/ocfs2/libocfs2/include
___________________________________________________________________
Name: svn:ignore
- cscope*
stamp-md5
.*.sw?
.*.cmd
+ cscope*
stamp-md5
.*.sw?
.*.cmd
ocfs2_err.h
Modified: trunk/ocfs2/libocfs2/include/bitmap.h
===================================================================
--- trunk/ocfs2/libocfs2/include/bitmap.h 2004-08-09 21:11:06 UTC (rev 193)
+++ trunk/ocfs2/libocfs2/include/bitmap.h 2004-08-09 21:40:25 UTC (rev 194)
@@ -46,7 +46,6 @@
ocfs2_filesys *b_fs;
uint64_t b_set_bits;
uint64_t b_total_bits;
- size_t b_size;
char *b_description;
struct ocfs2_bitmap_operations *b_ops;
ocfs2_cached_inode *b_cinode; /* Cached inode this
@@ -69,14 +68,13 @@
int bc_set_bits;
uint32_t bc_cpos; /* If this bitmap is stored
on disk, where it lives */
- size_t bc_size; /* Allocated bytes */
char *bc_bitmap;
};
errcode_t ocfs2_bitmap_new(ocfs2_filesys *fs,
uint64_t total_bits,
- char *description,
+ const char *description,
struct ocfs2_bitmap_operations *ops,
void *private_data,
ocfs2_bitmap **ret_bitmap);
@@ -96,4 +94,10 @@
uint64_t bitno, int *oldval);
errcode_t ocfs2_bitmap_test_generic(ocfs2_bitmap *bitmap,
uint64_t bitno, int *val);
+errcode_t ocfs2_bitmap_set_holes(ocfs2_bitmap *bitmap,
+ uint64_t bitno, int *oldval);
+errcode_t ocfs2_bitmap_clear_holes(ocfs2_bitmap *bitmap,
+ uint64_t bitno, int *oldval);
+errcode_t ocfs2_bitmap_test_holes(ocfs2_bitmap *bitmap,
+ uint64_t bitno, int *val);
#endif /* _BITMAP_H */
Modified: trunk/ocfs2/libocfs2/include/ocfs2.h
===================================================================
--- trunk/ocfs2/libocfs2/include/ocfs2.h 2004-08-09 21:11:06 UTC (rev 193)
+++ trunk/ocfs2/libocfs2/include/ocfs2.h 2004-08-09 21:40:25 UTC (rev 194)
@@ -291,6 +291,12 @@
errcode_t ocfs2_get_next_inode(ocfs2_inode_scan *scan,
uint64_t *blkno, char *inode);
+errcode_t ocfs2_cluster_bitmap_new(ocfs2_filesys *fs,
+ const char *description,
+ ocfs2_bitmap **ret_bitmap);
+errcode_t ocfs2_block_bitmap_new(ocfs2_filesys *fs,
+ const char *description,
+ ocfs2_bitmap **ret_bitmap);
void ocfs2_bitmap_free(ocfs2_bitmap *bitmap);
errcode_t ocfs2_bitmap_set(ocfs2_bitmap *bitmap, uint64_t bitno,
int *oldval);
More information about the Ocfs-tools-commits
mailing list