[sheepdog] [PATCH v3 2/5] add basic read/write function framwork for btree

Robin Dong robin.k.dong at gmail.com
Thu Oct 24 11:46:19 CEST 2013


B-tree is just a abstract structure so it need to call callback-function to read
and write nodes.

Signed-off-by: Robin Dong <sanbai at taobao.com>
---
 dog/cluster.c            |    2 +-
 dog/dog.h                |    9 +++++++++
 dog/vdi.c                |   38 ++++++++++++++++++++++++++++----------
 include/sheepdog_proto.h |   18 +++++++++---------
 lib/sd_inode.c           |    6 ++++--
 sheep/sheep_priv.h       |    9 +++++++++
 sheep/vdi.c              |   13 ++++++++++++-
 sheepfs/volume.c         |   39 +++++++++++++++++++++++++++++++++++++--
 8 files changed, 109 insertions(+), 25 deletions(-)

diff --git a/dog/cluster.c b/dog/cluster.c
index 62b78d0..b432302 100644
--- a/dog/cluster.c
+++ b/dog/cluster.c
@@ -259,7 +259,7 @@ static void fill_object_tree(uint32_t vid, const char *name, const char *tag,
 	/* fill data object id */
 	nr_objs = count_data_objs(i);
 	for (uint64_t idx = 0; idx < nr_objs; idx++) {
-		vdi_id = sd_inode_get_vdi(i, idx);
+		vdi_id = INODE_GET_VDI(i, idx);
 		if (vdi_id) {
 			uint64_t oid = vid_to_data_oid(vdi_id, idx);
 			object_tree_insert(oid, i->nr_copies, i->copy_policy);
diff --git a/dog/dog.h b/dog/dog.h
index 769fc6c..c2832bb 100644
--- a/dog/dog.h
+++ b/dog/dog.h
@@ -85,6 +85,15 @@ void show_progress(uint64_t done, uint64_t total, bool raw);
 size_t get_store_objsize(uint8_t copy_policy, uint64_t oid);
 bool is_erasure_oid(uint64_t oid, uint8_t policy);
 
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create);
+int read_btree_node(uint64_t id, void **mem, unsigned int len);
+
+#define INODE_GET_VDI(inode, idx) (sd_inode_get_vdi(read_btree_node, \
+							inode, idx))
+#define INODE_SET_VDI(inode, idx, vdi_id) (sd_inode_set_vdi(write_btree_node, \
+					read_btree_node, inode, idx, vdi_id))
+
 extern struct command vdi_command;
 extern struct command node_command;
 extern struct command cluster_command;
diff --git a/dog/vdi.c b/dog/vdi.c
index c50f886..faf06f0 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -58,6 +58,24 @@ struct get_vdi_info {
 	uint8_t copy_policy;
 };
 
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create)
+{
+	return sd_write_object(id, 0, mem, len, 0, 0, copies, copy_policy,
+			true, true);
+}
+
+int read_btree_node(uint64_t id, void **mem, unsigned int len)
+{
+	return sd_read_object(id, *mem, len, 0, true);
+}
+
+static inline bool is_data_obj_writeable(const struct sd_inode *inode,
+					 int idx)
+{
+	return inode->vdi_id == INODE_GET_VDI(inode, idx);
+}
+
 static void vdi_show_progress(uint64_t done, uint64_t total)
 {
 	return show_progress(done, total, false);
@@ -82,7 +100,7 @@ static void stat_data_objs(const struct sd_inode *inode, uint64_t *my_objs,
 	nr = count_data_objs(inode);
 
 	for (int i = 0; i < nr; i++) {
-		vdi_id = sd_inode_get_vdi(inode, i);
+		vdi_id = INODE_GET_VDI(inode, i);
 		if (vdi_id == 0)
 			continue;
 		if (vdi_id == vid) {
@@ -277,7 +295,7 @@ static int obj_info_filler(const char *sheep, uint64_t oid, struct sd_rsp *rsp,
 		if (info->success)
 			break;
 		info->success = true;
-		vdi_id = sd_inode_get_vdi(inode, info->idx);
+		vdi_id = INODE_GET_VDI(inode, info->idx);
 		if (vdi_id) {
 			info->data_oid = vid_to_data_oid(vdi_id, info->idx);
 			return 1;
@@ -647,7 +665,7 @@ static int vdi_clone(int argc, char **argv)
 		size_t size;
 
 		vdi_show_progress(idx * SD_DATA_OBJ_SIZE, inode->vdi_size);
-		vdi_id = sd_inode_get_vdi(inode, idx);
+		vdi_id = INODE_GET_VDI(inode, idx);
 		if (vdi_id) {
 			oid = vid_to_data_oid(vdi_id, idx);
 			ret = sd_read_object(oid, buf, SD_DATA_OBJ_SIZE, 0, true);
@@ -1207,7 +1225,7 @@ static int vdi_read(int argc, char **argv)
 	offset %= SD_DATA_OBJ_SIZE;
 	while (done < total) {
 		len = min(total - done, SD_DATA_OBJ_SIZE - offset);
-		vdi_id = sd_inode_get_vdi(inode, idx);
+		vdi_id = INODE_GET_VDI(inode, idx);
 		if (vdi_id) {
 			oid = vid_to_data_oid(vdi_id, idx);
 			ret = sd_read_object(oid, buf, len, offset, false);
@@ -1283,7 +1301,7 @@ static int vdi_write(int argc, char **argv)
 		flags = 0;
 		len = min(total - done, SD_DATA_OBJ_SIZE - offset);
 
-		vdi_id = sd_inode_get_vdi(inode, idx);
+		vdi_id = INODE_GET_VDI(inode, idx);
 		if (!vdi_id)
 			create = true;
 		else if (!is_data_obj_writeable(inode, idx)) {
@@ -1305,7 +1323,7 @@ static int vdi_write(int argc, char **argv)
 			total = done + len;
 		}
 
-		sd_inode_set_vdi(inode, idx, inode->vdi_id);
+		INODE_SET_VDI(inode, idx, inode->vdi_id);
 		oid = vid_to_data_oid(inode->vdi_id, idx);
 		ret = sd_write_object(oid, old_oid, buf, len, offset, flags,
 				      inode->nr_copies, inode->copy_policy,
@@ -1667,7 +1685,7 @@ int do_vdi_check(const struct sd_inode *inode)
 	max_idx = count_data_objs(inode);
 	vdi_show_progress(done, inode->vdi_size);
 	for (int idx = 0; idx < max_idx; idx++) {
-		vid = sd_inode_get_vdi(inode, idx);
+		vid = INODE_GET_VDI(inode, idx);
 		if (vid) {
 			oid = vid_to_data_oid(vid, idx);
 			queue_vdi_check_work(inode, oid, &done, wq);
@@ -1822,8 +1840,8 @@ static int vdi_backup(int argc, char **argv)
 	}
 
 	for (idx = 0; idx < nr_objs; idx++) {
-		uint32_t from_vid = sd_inode_get_vdi(from_inode, idx);
-		uint32_t to_vid = sd_inode_get_vdi(to_inode, idx);
+		uint32_t from_vid = INODE_GET_VDI(from_inode, idx);
+		uint32_t to_vid = INODE_GET_VDI(to_inode, idx);
 
 		if (to_vid == 0 && from_vid == 0)
 			continue;
@@ -1875,7 +1893,7 @@ static int restore_obj(struct obj_backup *backup, uint32_t vid,
 		       struct sd_inode *parent_inode)
 {
 	int ret;
-	uint32_t parent_vid = sd_inode_get_vdi(parent_inode, backup->idx);
+	uint32_t parent_vid = INODE_GET_VDI(parent_inode, backup->idx);
 	uint64_t parent_oid = 0;
 
 	if (parent_vid)
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index d393460..30ff397 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -225,6 +225,10 @@ struct sd_inode {
 	uint32_t data_vdi_id[MAX_DATA_OBJS];
 };
 
+typedef int (*write_node_fn)(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create);
+typedef int (*read_node_fn)(uint64_t id, void **mem, unsigned int len);
+
 struct sheepdog_vdi_attr {
 	char name[SD_MAX_VDI_LEN];
 	char tag[SD_MAX_VDI_TAG_LEN];
@@ -235,9 +239,11 @@ struct sheepdog_vdi_attr {
 	char value[SD_MAX_VDI_ATTR_VALUE_LEN];
 };
 
-uint32_t sd_inode_get_vdi(const struct sd_inode *inode, int idx);
-void sd_inode_set_vdi(struct sd_inode *inode, int idx, uint32_t vdi_id);
-void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi);
+extern uint32_t sd_inode_get_vdi(read_node_fn reader,
+		const struct sd_inode *inode, int idx);
+extern void sd_inode_set_vdi(write_node_fn writer, read_node_fn reader,
+		struct sd_inode *inode, int idx, uint32_t vdi_id);
+extern void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi);
 
 /* 64 bit FNV-1a non-zero initial basis */
 #define FNV1A_64_INIT ((uint64_t) 0xcbf29ce484222325ULL)
@@ -326,12 +332,6 @@ static inline uint64_t hash_64(uint64_t val, unsigned int bits)
 	return sd_hash_64(val) >> (64 - bits);
 }
 
-static inline bool is_data_obj_writeable(const struct sd_inode *inode,
-					 int idx)
-{
-	return inode->vdi_id == sd_inode_get_vdi(inode, idx);
-}
-
 static inline bool is_vdi_obj(uint64_t oid)
 {
 	return !!(oid & VDI_BIT);
diff --git a/lib/sd_inode.c b/lib/sd_inode.c
index 65a472a..c03ca03 100644
--- a/lib/sd_inode.c
+++ b/lib/sd_inode.c
@@ -2,12 +2,14 @@
 
 #include "sheepdog_proto.h"
 
-uint32_t sd_inode_get_vdi(const struct sd_inode *inode, int idx)
+uint32_t sd_inode_get_vdi(read_node_fn reader,
+		const struct sd_inode *inode, int idx)
 {
 	return inode->data_vdi_id[idx];
 }
 
-void sd_inode_set_vdi(struct sd_inode *inode, int idx, uint32_t vdi_id)
+void sd_inode_set_vdi(write_node_fn writer, read_node_fn reader,
+		struct sd_inode *inode, int idx, uint32_t vdi_id)
 {
 	inode->data_vdi_id[idx] = vdi_id;
 }
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 615d912..e28e1b1 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -375,6 +375,15 @@ void objlist_cache_remove(uint64_t oid);
 
 void put_request(struct request *req);
 
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create);
+int read_btree_node(uint64_t id, void **mem, unsigned int len);
+
+#define INODE_GET_VDI(inode, idx) (sd_inode_get_vdi(read_btree_node, \
+					inode, idx))
+#define INODE_SET_VDI(inode, idx, vdi_id) (sd_inode_set_vdi(write_btree_node,\
+					read_btree_node, inode, idx, vdi_id))
+
 /* Operations */
 
 const struct sd_op_template *get_sd_op(uint8_t opcode);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 27227b7..dc3f975 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -22,6 +22,17 @@ struct vdi_state_entry {
 static struct rb_root vdi_state_root = RB_ROOT;
 static struct sd_lock vdi_state_lock = SD_LOCK_INITIALIZER;
 
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create)
+{
+	return write_object(id, mem, len, 0, create == 1);
+}
+
+int read_btree_node(uint64_t id, void **mem, unsigned int len)
+{
+	return read_object(id, *mem, len, 0);
+}
+
 static int vdi_state_cmp(const struct vdi_state_entry *a,
 			 const struct vdi_state_entry *b)
 {
@@ -833,7 +844,7 @@ static void delete_one(struct work *work)
 	nr_objs = count_data_objs(inode);
 	for (nr_deleted = 0, i = 0; i < nr_objs; i++) {
 		uint64_t oid;
-		uint32_t vid = sd_inode_get_vdi(inode, i);
+		uint32_t vid = INODE_GET_VDI(inode, i);
 
 		if (!vid)
 			continue;
diff --git a/sheepfs/volume.c b/sheepfs/volume.c
index ab16ada..c2df32a 100644
--- a/sheepfs/volume.c
+++ b/sheepfs/volume.c
@@ -64,6 +64,22 @@ struct vdi_inode {
 static struct rb_root vdi_inode_tree = RB_ROOT;
 static struct sd_lock vdi_inode_tree_lock = SD_LOCK_INITIALIZER;
 
+
+static int write_btree_node(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create);
+static int read_btree_node(uint64_t id, void **mem, unsigned int len);
+
+#define INODE_GET_VDI(inode, idx) (sd_inode_get_vdi(\
+					read_btree_node, inode, idx))
+#define INODE_SET_VDI(inode, idx, vdi_id) (sd_inode_set_vdi(\
+			write_btree_node, read_btree_node, inode, idx, vdi_id))
+
+static inline bool is_data_obj_writeable(const struct sd_inode *inode,
+					 int idx)
+{
+	return inode->vdi_id == INODE_GET_VDI(inode, idx);
+}
+
 static int vdi_inode_cmp(const struct vdi_inode *a, const struct vdi_inode *b)
 {
 	return intcmp(a->vid, b->vid);
@@ -129,7 +145,7 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
 	if (is_data_obj(oid)) {
 		idx = data_oid_to_idx(oid);
 		assert(vdi);
-		vdi_id = sd_inode_get_vdi(vdi->inode, idx);
+		vdi_id = INODE_GET_VDI(vdi->inode, idx);
 		if (!vdi_id) {
 			/* if object doesn't exist, we'er done */
 			if (rw == VOLUME_READ) {
@@ -176,7 +192,7 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
 	}
 
 	if (create) {
-		sd_inode_set_vdi(vdi->inode, idx, vid);
+		INODE_SET_VDI(vdi->inode, idx, vid);
 		/* writeback inode update */
 		if (volume_rw_object((char *)&vid, vid_to_vdi_oid(vid),
 				     sizeof(vid),
@@ -231,6 +247,25 @@ static int volume_do_rw(const char *path, char *buf, size_t size,
 	return 0;
 }
 
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+				int copies, int copy_policy, int create)
+{
+	int ret;
+	ret = volume_rw_object(mem, id, len, 0, VOLUME_WRITE);
+	if (ret == len)
+		return SD_RES_SUCCESS;
+	return ret;
+}
+
+int read_btree_node(uint64_t id, void **mem, unsigned int len)
+{
+	int ret;
+	ret = volume_rw_object(*mem, id, len, 0, VOLUME_READ);
+	if (ret == len)
+		return SD_RES_SUCCESS;
+	return ret;
+}
+
 int volume_read(const char *path, char *buf, size_t size, off_t offset)
 {
 
-- 
1.7.1




More information about the sheepdog mailing list