[Ocfs2-tools-devel] [PATCH 1/6] libocfs2: add extent tree operations

Tiger Yang tiger.yang at oracle.com
Wed Jul 29 00:01:08 PDT 2009


This patch add extent tree operations, then we can handle
different extent trees.  Now we have three type extent tree,
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 |  194 ++++++++++++++++++++++++++++++++++++++++++++++++
 libocfs2/extent_tree.h |  107 ++++++++++++++++++++++++++
 libocfs2/xattr.h       |   19 +++++
 4 files changed, 322 insertions(+), 1 deletions(-)
 create mode 100644 libocfs2/extent_tree.c
 create mode 100644 libocfs2/extent_tree.h
 create mode 100644 libocfs2/xattr.h

diff --git a/libocfs2/Makefile b/libocfs2/Makefile
index 48cfe80..bd40d9a 100644
--- a/libocfs2/Makefile
+++ b/libocfs2/Makefile
@@ -74,7 +74,8 @@ CFILES = 		\
 	backup_super.c	\
 	feature_string.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..34bbc2d
--- /dev/null
+++ b/libocfs2/extent_tree.c
@@ -0,0 +1,194 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * extent_tree.c
+ *
+ * Copyright (C) 2004, 2008 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 "xattr.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_xattr_value_fill_root_el(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_xattr_value_root *xv = et->et_object;
+
+	et->et_root_el = &xv->xr_list;
+}
+
+static void ocfs2_xattr_value_set_last_eb_blk(struct ocfs2_extent_tree *et,
+					      uint64_t blkno)
+{
+	struct ocfs2_xattr_value_root *xv = et->et_object;
+
+	xv->xr_last_eb_blk = blkno;
+}
+
+static uint64_t ocfs2_xattr_value_get_last_eb_blk(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_xattr_value_root *xv = et->et_object;
+
+	return xv->xr_last_eb_blk;
+}
+
+static void ocfs2_xattr_value_update_clusters(struct ocfs2_extent_tree *et,
+					      uint32_t clusters)
+{
+	struct ocfs2_xattr_value_root *xv = et->et_object;
+
+	xv->xr_clusters += clusters;
+}
+
+static uint32_t ocfs2_xattr_value_get_clusters(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_xattr_value_root *xv = et->et_object;
+
+	return xv->xr_clusters;
+}
+
+static struct ocfs2_extent_tree_operations ocfs2_xattr_value_et_ops = {
+	.eo_set_last_eb_blk	= ocfs2_xattr_value_set_last_eb_blk,
+	.eo_get_last_eb_blk	= ocfs2_xattr_value_get_last_eb_blk,
+	.eo_update_clusters	= ocfs2_xattr_value_update_clusters,
+	.eo_get_clusters	= ocfs2_xattr_value_get_clusters,
+	.eo_fill_root_el	= ocfs2_xattr_value_fill_root_el,
+};
+
+static void ocfs2_xattr_tree_fill_root_el(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_xattr_block *xb = et->et_object;
+
+	et->et_root_el = &xb->xb_attrs.xb_root.xt_list;
+}
+
+static void ocfs2_xattr_tree_fill_max_leaf_clusters(ocfs2_filesys *fs,
+						struct ocfs2_extent_tree *et)
+{
+	et->et_max_leaf_clusters =
+		ocfs2_clusters_in_bytes(fs, OCFS2_MAX_XATTR_TREE_LEAF_SIZE);
+}
+
+static void ocfs2_xattr_tree_set_last_eb_blk(struct ocfs2_extent_tree *et,
+					     uint64_t blkno)
+{
+	struct ocfs2_xattr_block *xb = et->et_object;
+	struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root;
+
+	xt->xt_last_eb_blk = blkno;
+}
+
+static uint64_t ocfs2_xattr_tree_get_last_eb_blk(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_xattr_block *xb = et->et_object;
+	struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root;
+
+	return xt->xt_last_eb_blk;
+}
+
+static void ocfs2_xattr_tree_update_clusters(struct ocfs2_extent_tree *et,
+					     uint32_t clusters)
+{
+	struct ocfs2_xattr_block *xb = et->et_object;
+
+	xb->xb_attrs.xb_root.xt_clusters += clusters;
+}
+
+static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = {
+	.eo_set_last_eb_blk	= ocfs2_xattr_tree_set_last_eb_blk,
+	.eo_get_last_eb_blk	= ocfs2_xattr_tree_get_last_eb_blk,
+	.eo_update_clusters	= ocfs2_xattr_tree_update_clusters,
+	.eo_fill_root_el	= ocfs2_xattr_tree_fill_root_el,
+	.eo_fill_max_leaf_clusters = ocfs2_xattr_tree_fill_max_leaf_clusters,
+};
+
+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);
+}
+
+void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
+					ocfs2_filesys *fs,
+					char *buf)
+{
+	__ocfs2_init_extent_tree(et, fs, buf, buf, &ocfs2_xattr_tree_et_ops);
+}
+
+void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
+					ocfs2_filesys *fs,
+					char *buf,
+					struct ocfs2_xattr_value_root *xv)
+{
+	__ocfs2_init_extent_tree(et, fs, buf, xv,
+				 &ocfs2_xattr_value_et_ops);
+}
+
diff --git a/libocfs2/extent_tree.h b/libocfs2/extent_tree.h
new file mode 100644
index 0000000..0a3d36c
--- /dev/null
+++ b/libocfs2/extent_tree.h
@@ -0,0 +1,107 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * extent_tree.h
+ *
+ * Copyright (C) 2004, 2008 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_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
+					ocfs2_filesys *fs,
+					char *buf,
+					struct ocfs2_xattr_value_root *xv);
+errcode_t ocfs2_tree_extend_allocation(ocfs2_cached_inode *ci,
+					uint32_t new_clusters,
+					struct ocfs2_extent_tree *et);
+void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
+					ocfs2_filesys *fs,
+					char *buf);
+errcode_t ocfs2_tree_insert_extent(ocfs2_cached_inode *ci,
+				   uint32_t cpos, uint64_t c_blkno,
+				   uint32_t clusters, uint16_t flag,
+				   struct ocfs2_extent_tree *et);
+void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
+				   ocfs2_filesys *fs,
+				   char *buf);
diff --git a/libocfs2/xattr.h b/libocfs2/xattr.h
new file mode 100644
index 0000000..ae8793a
--- /dev/null
+++ b/libocfs2/xattr.h
@@ -0,0 +1,19 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * xattr.h
+ *
+ * Copyright (C) 2004, 2008 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.
+ */
+
+#define OCFS2_MAX_XATTR_TREE_LEAF_SIZE  65536
+
-- 
1.5.4.1




More information about the Ocfs2-tools-devel mailing list