[sheepdog] [PATCH v2 03/11] sheep: introduce generational reference counting for object reclaim

MORITA Kazutaka morita.kazutaka at gmail.com
Tue Jun 18 19:14:23 CEST 2013


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

Generational reference counting is an algorithm to reclaim data
efficiently without race conditions on distributed system.  This
extends vdi objects structure to store generational reference counts,
and increments the counts when creating snapshots.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 include/sheepdog_proto.h |    9 +++++++--
 sheep/vdi.c              |    8 +++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index beef0a6..bb0f253 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -101,8 +101,7 @@
 #define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
 
 #define SD_INODE_SIZE (sizeof(struct sd_inode))
-#define SD_INODE_HEADER_SIZE (sizeof(struct sd_inode) - \
-			      sizeof(uint32_t) * MAX_DATA_OBJS)
+#define SD_INODE_HEADER_SIZE offsetof(struct sd_inode, data_vdi_id)
 #define SD_ATTR_OBJ_SIZE (sizeof(struct sheepdog_vdi_attr))
 #define CURRENT_VDI_ID 0
 
@@ -193,6 +192,11 @@ struct sd_rsp {
 	};
 };
 
+struct generation_reference {
+	int32_t generation;
+	int32_t count;
+};
+
 struct sd_inode {
 	char name[SD_MAX_VDI_LEN];
 	char tag[SD_MAX_VDI_TAG_LEN];
@@ -209,6 +213,7 @@ struct sd_inode {
 	uint32_t parent_vdi_id;
 	uint32_t child_vdi_id[MAX_CHILDREN];
 	uint32_t data_vdi_id[MAX_DATA_OBJS];
+	struct generation_reference data_ref[MAX_DATA_OBJS];
 };
 
 struct sheepdog_vdi_attr {
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 096244a..988145d 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -291,6 +291,12 @@ static int create_vdi_obj(struct vdi_iocb *iocb, uint32_t new_vid,
 			ret = SD_RES_NO_BASE_VDI;
 			goto out;
 		}
+
+		for (i = 0; i < ARRAY_SIZE(base->data_ref); i++) {
+			base->data_ref[i].count++;
+			new->data_ref[i].generation =
+				base->data_ref[i].generation + 1;
+		}
 	}
 
 	if (iocb->create_snapshot && cur_vid != iocb->base_vid) {
@@ -305,7 +311,7 @@ static int create_vdi_obj(struct vdi_iocb *iocb, uint32_t new_vid,
 
 	if (iocb->base_vid) {
 		ret = write_object(vid_to_vdi_oid(iocb->base_vid), (char *)base,
-				   SD_INODE_HEADER_SIZE, 0, false);
+				   SD_INODE_SIZE, 0, false);
 		if (ret != 0) {
 			sd_printf(SDOG_ERR, "failed");
 			ret = SD_RES_BASE_VDI_WRITE;
-- 
1.7.9.5




More information about the sheepdog mailing list