[sheepdog] [PATCH v6 7/9] use callback to implement fill_object_tree() and delete_one() for hyper volume

Robin Dong robin.k.dong at gmail.com
Mon Nov 11 07:55:33 CET 2013


For fill_object_tree() and delete_one() to support hyper volume by using traverse_btree()

Signed-off-by: Robin Dong <sanbai at taobao.com>
---
 dog/cluster.c |   33 ++++++++++++++++++++-----
 sheep/vdi.c   |   72 +++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 81 insertions(+), 24 deletions(-)

diff --git a/dog/cluster.c b/dog/cluster.c
index 78586a5..ecc4ec2 100644
--- a/dog/cluster.c
+++ b/dog/cluster.c
@@ -241,13 +241,29 @@ out:
 	return ret;
 }
 
+static void fill_cb(void *data, enum btree_node_type type, void *arg)
+{
+	struct sd_extent *ext;
+	struct sd_inode *inode = (struct sd_inode *)arg;
+	uint64_t oid;
+
+	if (type == BTREE_EXT) {
+		ext = (struct sd_extent *)data;
+		if (ext->vdi_id) {
+			oid = vid_to_data_oid(ext->vdi_id, ext->idx);
+			object_tree_insert(oid, inode->nr_copies,
+					   inode->copy_policy);
+		}
+	}
+}
+
 static void fill_object_tree(uint32_t vid, const char *name, const char *tag,
 			     uint32_t snapid, uint32_t flags,
 			     const struct sd_inode *i, void *data)
 {
 	uint64_t vdi_oid = vid_to_vdi_oid(vid), vmstate_oid;
 	uint32_t vdi_id;
-	int nr_objs, nr_vmstate_object;
+	uint32_t nr_objs, nr_vmstate_object;
 
 	/* ignore active vdi */
 	if (!vdi_is_snapshot(i))
@@ -257,18 +273,21 @@ static void fill_object_tree(uint32_t vid, const char *name, const char *tag,
 	object_tree_insert(vdi_oid, i->nr_copies, i->copy_policy);
 
 	/* fill data object id */
-	nr_objs = count_data_objs(i);
-	for (uint64_t idx = 0; idx < nr_objs; idx++) {
-		vdi_id = INODE_GET_VID(i, idx);
-		if (vdi_id) {
+	if (i->store_policy == 0) {
+		nr_objs = count_data_objs(i);
+		for (uint32_t idx = 0; idx < nr_objs; idx++) {
+			vdi_id = INODE_GET_VID(i, idx);
+			if (!vdi_id)
+				continue;
 			uint64_t oid = vid_to_data_oid(vdi_id, idx);
 			object_tree_insert(oid, i->nr_copies, i->copy_policy);
 		}
-	}
+	} else
+		traverse_btree(dog_bnode_reader, i, fill_cb, &i);
 
 	/* fill vmstate object id */
 	nr_vmstate_object = DIV_ROUND_UP(i->vm_state_size, SD_DATA_OBJ_SIZE);
-	for (int idx = 0; idx < nr_vmstate_object; idx++) {
+	for (uint32_t idx = 0; idx < nr_vmstate_object; idx++) {
 		vmstate_oid = vid_to_vmstate_oid(vid, idx);
 		object_tree_insert(vmstate_oid, i->nr_copies, i->copy_policy);
 	}
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 3d4af76..77308fe 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -834,11 +834,43 @@ static int notify_vdi_deletion(uint32_t vdi_id)
 	return ret;
 }
 
+struct delete_arg {
+	const struct sd_inode *inode;
+	uint32_t *nr_deleted;
+};
+
+static void delete_cb(void *data, enum btree_node_type type, void *arg)
+{
+	struct sd_extent *ext;
+	struct delete_arg *darg = (struct delete_arg *)arg;
+	uint64_t oid;
+	int ret;
+
+	if (type != BTREE_EXT)
+		return;
+
+	ext = (struct sd_extent *)data;
+	if (ext->vdi_id) {
+		oid = vid_to_data_oid(ext->vdi_id, ext->idx);
+		if (ext->vdi_id != darg->inode->vdi_id)
+			sd_debug("object %" PRIx64 " is base's data, would"
+				 " not be deleted.", oid);
+		else {
+			ret = remove_object(oid);
+			if (ret != SD_RES_SUCCESS)
+				sd_err("remove object %" PRIx64 " fail, %d",
+				       oid, ret);
+			(*(darg->nr_deleted))++;
+		}
+	}
+}
+
 static void delete_one(struct work *work)
 {
 	struct deletion_work *dw = container_of(work, struct deletion_work, work);
 	uint32_t vdi_id = *(dw->buf + dw->count - dw->done - 1);
-	int ret, i, nr_deleted, nr_objs;
+	int ret;
+	uint32_t i, nr_deleted, nr_objs;
 	struct sd_inode *inode = NULL;
 
 	sd_debug("%d %d, %16x", dw->done, dw->count, vdi_id);
@@ -860,27 +892,33 @@ static void delete_one(struct work *work)
 	if (inode->vdi_size == 0 && vdi_is_deleted(inode))
 		goto out;
 
-	nr_objs = count_data_objs(inode);
-	for (nr_deleted = 0, i = 0; i < nr_objs; i++) {
-		uint64_t oid;
-		uint32_t vid = INODE_GET_VID(inode, i);
+	if (inode->store_policy == 0) {
+		nr_objs = count_data_objs(inode);
+		for (nr_deleted = 0, i = 0; i < nr_objs; i++) {
+			uint64_t oid;
+			uint32_t vid = INODE_GET_VID(inode, i);
 
-		if (!vid)
-			continue;
+			if (!vid)
+				continue;
 
-		oid = vid_to_data_oid(vid, i);
+			oid = vid_to_data_oid(vid, i);
 
-		if (vid != inode->vdi_id) {
-			sd_debug("object %" PRIx64 " is base's data, would"
-				 " not be deleted.", oid);
-			continue;
-		}
+			if (vid != inode->vdi_id) {
+				sd_debug("object %" PRIx64 " is base's data, "
+					 "would not be deleted.", oid);
+				continue;
+			}
 
-		ret = remove_object(oid);
-		if (ret != SD_RES_SUCCESS)
-			sd_err("remove object %" PRIx64 " fail, %d", oid, ret);
+			ret = remove_object(oid);
+			if (ret != SD_RES_SUCCESS)
+				sd_err("remove object %" PRIx64 " fail, %d",
+				       oid, ret);
 
-		nr_deleted++;
+			nr_deleted++;
+		}
+	} else {
+		struct delete_arg arg = {inode, &nr_deleted};
+		traverse_btree(sheep_bnode_reader, inode, delete_cb, &arg);
 	}
 
 	if (vdi_is_deleted(inode))
-- 
1.7.1




More information about the sheepdog mailing list