[Sheepdog] [PATCH 2/2] remove oids from object list cache when deleting a vdi

Li Wenpeng levin108 at gmail.com
Thu Apr 26 04:45:32 CEST 2012


From: levin li <xingke.lwp at taobao.com>

when deleting data objects, we need to remove their oid
from all the nodes' objlist cache, so we record which objects
are deleted, and notify a deletion list to all the nodes,
every node removes the oids in the list from its cache.

Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 include/sheep.h    |    1 +
 sheep/ops.c        |   17 +++++++++++++++++
 sheep/sheep_priv.h |    1 +
 sheep/store.c      |   16 ++++++++++++++++
 sheep/vdi.c        |   50 ++++++++++++++++++++++++++++++++++++++++++++++----
 5 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index fc2ac58..b80bc01 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -45,6 +45,7 @@
 #define SD_OP_CLEANUP        0x94
 #define SD_OP_TRACE          0x95
 #define SD_OP_TRACE_CAT      0x96
+#define SD_OP_NOTIFY_VDI_DEL 0x97
 
 #define SD_FLAG_CMD_IO_LOCAL   0x0010
 #define SD_FLAG_CMD_RECOVERY 0x0020
diff --git a/sheep/ops.c b/sheep/ops.c
index 54e866c..b90c16b 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -452,6 +452,17 @@ static int cluster_cleanup(const struct sd_req *req, struct sd_rsp *rsp,
 	return ret;
 }
 
+static int cluster_notify_vdi_deletion(const struct sd_req *req, struct sd_rsp *rsp,
+				void *data)
+{
+	int count = req->data_length / sizeof(uint64_t);
+	uint64_t *oids = data;
+
+	del_vdi_from_objlist_cache(oids, count);
+
+	return SD_RES_SUCCESS;
+}
+
 static int cluster_restore(const struct sd_req *req, struct sd_rsp *rsp,
 			   void *data)
 {
@@ -607,6 +618,12 @@ static struct sd_op_template sd_ops[] = {
 		.process_main = cluster_cleanup,
 	},
 
+	[SD_OP_NOTIFY_VDI_DEL] = {
+		.type = SD_OP_TYPE_CLUSTER,
+		.force = 1,
+		.process_main = cluster_notify_vdi_deletion,
+	},
+
 	/* local operations */
 	[SD_OP_GET_STORE_LIST] = {
 		.type = SD_OP_TYPE_LOCAL,
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 1c27808..4330a62 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -292,6 +292,7 @@ void resume_recovery_work(void);
 int is_recoverying_oid(uint64_t oid);
 int node_in_recovery(void);
 
+int del_vdi_from_objlist_cache(uint64_t *oids, int count);
 int write_object(struct sd_vnode *e,
 		 int vnodes, int zones, uint32_t node_version,
 		 uint64_t oid, char *data, unsigned int datalen,
diff --git a/sheep/store.c b/sheep/store.c
index dac0bff..350c5af 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -133,6 +133,22 @@ static int check_and_insert_objlist_cache(uint64_t oid)
 	return 0;
 }
 
+int del_vdi_from_objlist_cache(uint64_t *oids, int count)
+{
+	int i;
+	dprintf("%d\n", count);
+
+	for (i = 0; i < count; i++) {
+		dprintf("remove oid %" PRIx64 " from objlist cache\n", oids[i]);
+		pthread_rwlock_wrlock(&obj_list_cache.lock);
+		if (!objlist_cache_rb_remove(&obj_list_cache.root, oids[i]))
+			obj_list_cache.cache_size--;
+		pthread_rwlock_unlock(&obj_list_cache.lock);
+	}
+
+	return 0;
+}
+
 static int obj_cmp(const void *oid1, const void *oid2)
 {
 	const uint64_t hval1 = fnv_64a_buf((void *)oid1, sizeof(uint64_t), FNV1A_64_INIT);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 6277de8..a654e3d 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -10,6 +10,7 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <sys/time.h>
 
 #include "sheepdog_proto.h"
@@ -449,6 +450,39 @@ out:
 	return ret;
 }
 
+static int notify_deletion(uint64_t *oids, uint32_t count)
+{
+	int fd, ret;
+	unsigned int wlen, rlen = 0;
+	struct sd_vdi_req hdr;
+	char host[128];
+
+	addr_to_str(host, sizeof(host), sys->this_node.addr, 0);
+
+	fd = connect_to(host, sys->this_node.port);
+	if (fd < 0) {
+		eprintf("connect to local node fail\n");
+		return -1;
+	}
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.proto_ver = SD_PROTO_VER;
+	hdr.opcode = SD_OP_NOTIFY_VDI_DEL;
+	hdr.flags = SD_FLAG_CMD_WRITE;
+	hdr.data_length = sizeof(uint64_t) * count;
+	wlen = hdr.data_length;
+
+	ret = exec_req(fd, (struct sd_req *)&hdr, oids, &wlen, &rlen);
+	close(fd);
+
+	if (ret < 0) {
+		eprintf("send request fail\n");
+		return -1;
+	}
+
+	return 0;
+}
 
 static void delete_one(struct work *work)
 {
@@ -456,6 +490,8 @@ static void delete_one(struct work *work)
 	uint32_t vdi_id = *(dw->buf + dw->count - dw->done - 1);
 	int ret, i;
 	struct sheepdog_inode *inode = NULL;
+	uint64_t deleted_oids[MAX_DATA_OBJS];
+	uint32_t deleted_count = 0;
 
 	eprintf("%d %d, %16x\n", dw->done, dw->count, vdi_id);
 
@@ -475,6 +511,8 @@ static void delete_one(struct work *work)
 	}
 
 	for (i = 0; i < MAX_DATA_OBJS; i++) {
+		uint64_t oid;
+
 		if (!inode->data_vdi_id[i])
 			continue;
 
@@ -484,21 +522,25 @@ static void delete_one(struct work *work)
 			continue;
 		}
 
+		oid = vid_to_data_oid(inode->data_vdi_id[i], i);
+
 		ret = remove_object(dw->entries, dw->nr_vnodes, dw->nr_zones, dw->epoch,
-			      vid_to_data_oid(inode->data_vdi_id[i], i),
-			      inode->nr_copies);
+			      oid, inode->nr_copies);
 
 		if (ret != SD_RES_SUCCESS)
 			dw->delete_error = 1;
-		else
+		else {
+			deleted_oids[deleted_count++] = oid;
 			inode->data_vdi_id[i] = 0;
+		}
 	}
 
+	notify_deletion(deleted_oids, deleted_count);
+
 	if (dw->delete_error)
 		write_object(dw->entries, dw->nr_vnodes, dw->nr_zones, dw->epoch,
 				vid_to_vdi_oid(vdi_id), (void *)inode, sizeof(*inode),
 				0, 0, inode->nr_copies, 0);
-
 out:
 	free(inode);
 }
-- 
1.7.1




More information about the sheepdog mailing list