[Ocfs2-tools-devel] [PATCH 01/10] libocfs2: add extent tree operations

Tao Ma tao.ma at oracle.com
Wed Sep 30 07:27:38 PDT 2009


From: Tiger Yang <tiger.yang at oracle.com>

This patch add extent tree structures and operations, with them
we can handle different types of extent trees. Now we have three types
of the trees, such as file data tree, xattr record tree and xattr value tree.

Signed-off-by: Tiger Yang <tiger.yang at oracle.com>
---
 libocfs2/Makefile      |    3 +-
 libocfs2/extent_tree.c |   84 +++++++++++++++++++++++++++++++++++++++++++
 libocfs2/extent_tree.h |   93 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+), 1 deletions(-)
 create mode 100644 libocfs2/extent_tree.c
 create mode 100644 libocfs2/extent_tree.h

diff --git a/libocfs2/Makefile b/libocfs2/Makefile
index eeb854a..8e94cc3 100644
--- a/libocfs2/Makefile
+++ b/libocfs2/Makefile
@@ -75,7 +75,8 @@ CFILES = 		\
 	feature_string.c\
 	quota.c		\
 	image.c		\
-	xattr.c
+	xattr.c		\
+	extent_tree.c
 
 HFILES =		\
 	bitmap.h	\
diff --git a/libocfs2/extent_tree.c b/libocfs2/extent_tree.c
new file mode 100644
index 0000000..ee0a2b3
--- /dev/null
+++ b/libocfs2/extent_tree.c
@@ -0,0 +1,84 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * extent_tree.c
+ *
+ * Copyright (C) 2009 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "ocfs2/byteorder.h"
+#include "ocfs2/ocfs2.h"
+#include "extent_tree.h"
+
+static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et,
+					 uint64_t blkno)
+{
+	struct ocfs2_dinode *di = et->et_object;
+
+	di->i_last_eb_blk = blkno;
+}
+
+static uint64_t ocfs2_dinode_get_last_eb_blk(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_dinode *di = et->et_object;
+
+	return di->i_last_eb_blk;
+}
+
+static void ocfs2_dinode_update_clusters(struct ocfs2_extent_tree *et,
+					 uint32_t clusters)
+{
+	struct ocfs2_dinode *di = et->et_object;
+
+	di->i_clusters += clusters;
+}
+static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_dinode *di = et->et_object;
+
+	et->et_root_el = &di->id2.i_list;
+}
+
+static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = {
+	.eo_set_last_eb_blk	= ocfs2_dinode_set_last_eb_blk,
+	.eo_get_last_eb_blk	= ocfs2_dinode_get_last_eb_blk,
+	.eo_update_clusters	= ocfs2_dinode_update_clusters,
+	.eo_fill_root_el	= ocfs2_dinode_fill_root_el,
+};
+
+static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et,
+				     ocfs2_filesys *fs,
+				     char *buf,
+				     void *obj,
+				     struct ocfs2_extent_tree_operations *ops)
+{
+	et->et_ops = ops;
+	et->et_root_buf = buf;
+	et->et_object = obj;
+
+	et->et_ops->eo_fill_root_el(et);
+	if (!et->et_ops->eo_fill_max_leaf_clusters)
+		et->et_max_leaf_clusters = 0;
+	else
+		et->et_ops->eo_fill_max_leaf_clusters(fs, et);
+}
+
+void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
+				   ocfs2_filesys *fs,
+				   char *buf)
+{
+	__ocfs2_init_extent_tree(et, fs, buf,
+				 buf, &ocfs2_dinode_et_ops);
+}
diff --git a/libocfs2/extent_tree.h b/libocfs2/extent_tree.h
new file mode 100644
index 0000000..b0df721
--- /dev/null
+++ b/libocfs2/extent_tree.h
@@ -0,0 +1,93 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * extent_tree.h
+ *
+ * Copyright (C) 2009 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.
+ */
+
+struct ocfs2_extent_tree {
+	struct ocfs2_extent_tree_operations	*et_ops;
+	char					*et_root_buf;
+	struct ocfs2_extent_list		*et_root_el;
+	void					*et_object;
+	uint32_t				et_max_leaf_clusters;
+};
+
+/*
+ * Operations for a specific extent tree type.
+ *
+ * To implement an on-disk btree (extent tree) type in ocfs2, add
+ * an ocfs2_extent_tree_operations structure and the matching
+ * ocfs2_init_<thingy>_extent_tree() function.  That's pretty much it
+ * for the allocation portion of the extent tree.
+ */
+struct ocfs2_extent_tree_operations {
+	/*
+	 * last_eb_blk is the block number of the right most leaf extent
+	 * block.  Most on-disk structures containing an extent tree store
+	 * this value for fast access.  The ->eo_set_last_eb_blk() and
+	 * ->eo_get_last_eb_blk() operations access this value.  They are
+	 *  both required.
+	 */
+	void (*eo_set_last_eb_blk)(struct ocfs2_extent_tree *et,
+				   uint64_t blkno);
+	uint64_t (*eo_get_last_eb_blk)(struct ocfs2_extent_tree *et);
+
+	/*
+	 * The on-disk structure usually keeps track of how many total
+	 * clusters are stored in this extent tree.  This function updates
+	 * that value.  new_clusters is the delta, and must be
+	 * added to the total.  Required.
+	 */
+	void (*eo_update_clusters)(/*struct inode *inode,*/
+				   struct ocfs2_extent_tree *et,
+				   uint32_t new_clusters);
+	uint32_t (*eo_get_clusters)(struct ocfs2_extent_tree *et);
+
+	/*
+	 * If ->eo_insert_check() exists, it is called before rec is
+	 * inserted into the extent tree.  It is optional.
+	 */
+	/*
+	int (*eo_insert_check)(struct inode *inode,
+			       struct ocfs2_extent_tree *et,
+			       struct ocfs2_extent_rec *rec);
+	int (*eo_sanity_check)(struct inode *inode,
+			       struct ocfs2_extent_tree *et);
+	*/
+	int (*eo_sanity_check)(struct ocfs2_extent_tree *et);
+
+	/*
+	 * --------------------------------------------------------------
+	 * The remaining are internal to ocfs2_extent_tree and don't have
+	 * accessor functions
+	 */
+
+	/*
+	 * ->eo_fill_root_el() takes et->et_object and sets et->et_root_el.
+	 * It is required.
+	 */
+	void (*eo_fill_root_el)(struct ocfs2_extent_tree *et);
+
+	/*
+	 * ->eo_fill_max_leaf_clusters sets et->et_max_leaf_clusters if
+	 * it exists.  If it does not, et->et_max_leaf_clusters is set
+	 * to 0 (unlimited).  Optional.
+	 */
+	void (*eo_fill_max_leaf_clusters)(ocfs2_filesys *fs,
+					  struct ocfs2_extent_tree *et);
+};
+
+void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
+				   ocfs2_filesys *fs,
+				   char *buf);
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list