[Sheepdog] [PATCH] add vdi creation time to the vdi attribute header

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Tue Oct 11 07:51:31 CEST 2011


Currently, Sheepdog doesn't clean up vdi attributes when we delete the
vdi.  So if we create a new vdi whose name was used before, we could
read the old attribute.

This patch adds a vdi creation time to the attribute header and checks
whether the attribute belongs to the current vdi.  Note that this is a
transitional approach. In future, we should remove vdi attributes when
we remove the vdi.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/vdi.c             |   17 +++++++----------
 include/sheepdog_proto.h |   13 +++++++++++--
 sheep/group.c            |    7 ++++---
 sheep/sheep_priv.h       |    7 ++++---
 sheep/vdi.c              |   39 ++++++++++++++++++++++-----------------
 5 files changed, 48 insertions(+), 35 deletions(-)

diff --git a/collie/vdi.c b/collie/vdi.c
index 27b0595..18c0171 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -791,16 +791,13 @@ static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
 	struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
 	int fd, ret;
 	unsigned int wlen, rlen;
-	char buf[SD_ATTR_HEADER_SIZE];
+	struct sheepdog_vdi_attr vattr;
 
-	memset(buf, 0, sizeof(buf));
-	strncpy(buf, vdiname, SD_MAX_VDI_LEN);
-	strncpy(buf + SD_MAX_VDI_LEN, vdi_cmd_data.snapshot_tag,
-		SD_MAX_VDI_TAG_LEN);
-	memcpy(buf + SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN,
-	       &vdi_cmd_data.snapshot_id, sizeof(uint32_t));
-	strncpy(buf + SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN + sizeof(uint32_t),
-		key, SD_MAX_VDI_ATTR_KEY_LEN);
+	memset(&vattr, 0, sizeof(vattr));
+	strncpy(vattr.name, vdiname, SD_MAX_VDI_LEN);
+	strncpy(vattr.tag, vdi_cmd_data.snapshot_tag, SD_MAX_VDI_TAG_LEN);
+	vattr.snap_id = vdi_cmd_data.snapshot_id;
+	strncpy(vattr.key, key, SD_MAX_VDI_ATTR_KEY_LEN);
 
 	fd = connect_to(sdhost, sdport);
 	if (fd < 0) {
@@ -821,7 +818,7 @@ static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
 	if (excl)
 		hdr.flags |= SD_FLAG_CMD_EXCL;
 
-	ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+	ret = exec_req(fd, (struct sd_req *)&hdr, &vattr, &wlen, &rlen);
 	if (ret) {
 		ret = SD_RES_EIO;
 		goto out;
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 2b042f4..75e27e5 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -87,8 +87,7 @@
 #define SD_INODE_SIZE (sizeof(struct sheepdog_inode))
 #define SD_INODE_HEADER_SIZE (sizeof(struct sheepdog_inode) - \
 			      sizeof(uint32_t) * MAX_DATA_OBJS)
-#define SD_ATTR_HEADER_SIZE (SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN + \
-			     sizeof(uint32_t) + SD_MAX_VDI_ATTR_KEY_LEN)
+#define SD_ATTR_HEADER_SIZE (sizeof(struct sheepdog_vdi_attr))
 #define CURRENT_VDI_ID 0
 
 struct sd_req {
@@ -185,6 +184,16 @@ struct sheepdog_inode {
 	uint32_t data_vdi_id[MAX_DATA_OBJS];
 };
 
+struct sheepdog_vdi_attr {
+	char name[SD_MAX_VDI_LEN];
+	char tag[SD_MAX_VDI_TAG_LEN];
+	uint64_t ctime;
+	uint32_t snap_id;
+	uint32_t value_len;
+	char key[SD_MAX_VDI_ATTR_KEY_LEN];
+	char value[0];
+};
+
 /*
  * 64 bit FNV-1a non-zero initial basis
  */
diff --git a/sheep/group.c b/sheep/group.c
index f6743f5..0a6d0b0 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -853,6 +853,7 @@ static void vdi_op(struct vdi_op_message *msg)
 	void *data = msg->data;
 	int ret = SD_RES_SUCCESS;
 	uint32_t vid = 0, attrid = 0, nr_copies = sys->nr_sobjs;
+	uint64_t ctime = 0;
 
 	switch (hdr->opcode) {
 	case SD_OP_NEW_VDI:
@@ -871,14 +872,14 @@ static void vdi_op(struct vdi_op_message *msg)
 			break;
 		}
 		ret = lookup_vdi(hdr->epoch, data, hdr->data_length, &vid,
-				 hdr->snapid, &nr_copies);
+				 hdr->snapid, &nr_copies, NULL);
 		if (ret != SD_RES_SUCCESS)
 			break;
 		break;
 	case SD_OP_GET_VDI_ATTR:
 		ret = lookup_vdi(hdr->epoch, data,
 				 min(SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN, hdr->data_length),
-				 &vid, hdr->snapid, &nr_copies);
+				 &vid, hdr->snapid, &nr_copies, &ctime);
 		if (ret != SD_RES_SUCCESS)
 			break;
 		/* the curernt vdi id can change if we take the snapshot,
@@ -886,7 +887,7 @@ static void vdi_op(struct vdi_op_message *msg)
 		vid = fnv_64a_buf(data, strlen(data), FNV1A_64_INIT);
 		vid &= SD_NR_VDIS - 1;
 		ret = get_vdi_attr(hdr->epoch, data, hdr->data_length, vid,
-				   &attrid, nr_copies,
+				   &attrid, nr_copies, ctime,
 				   hdr->flags & SD_FLAG_CMD_CREAT,
 				   hdr->flags & SD_FLAG_CMD_EXCL);
 		break;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index e2fcb40..b292548 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -175,12 +175,13 @@ int del_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
 	    uint32_t snapid, unsigned int *nr_copies);
 
 int lookup_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
-	       uint32_t snapid, unsigned int *nr_copies);
+	       uint32_t snapid, unsigned int *nr_copies, uint64_t *ctime);
 
 int read_vdis(char *data, int len, unsigned int *rsp_len);
 
-int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
-		 uint32_t *attrid, int copies, int creat, int excl);
+int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
+		 uint32_t vid, uint32_t *attrid, int copies, uint64_t ctime,
+		 int creat, int excl);
 
 int get_ordered_sd_node_list(struct sheepdog_node_list_entry *entries);
 void setup_ordered_sd_vnode_list(struct request *req);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 392d429..1526afe 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -159,7 +159,7 @@ out:
 static int find_first_vdi(uint32_t epoch, unsigned long start, unsigned long end,
 			  char *name, char *tag, uint32_t snapid, uint32_t *vid,
 			  unsigned long *deleted_nr, uint32_t *next_snap,
-			  unsigned int *nr_copies)
+			  unsigned int *nr_copies, uint64_t *ctime)
 {
 	struct sheepdog_vnode_list_entry *entries;
 	struct sheepdog_inode *inode = NULL;
@@ -206,6 +206,8 @@ static int find_first_vdi(uint32_t epoch, unsigned long start, unsigned long end
 			*next_snap = inode->snap_id + 1;
 			*vid = inode->vdi_id;
 			*nr_copies = inode->nr_copies;
+			if (ctime)
+				*ctime = inode->ctime;
 			ret = SD_RES_SUCCESS;
 			goto out;
 		}
@@ -226,7 +228,7 @@ out:
 static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
 			 char *tag, uint32_t snapid, uint32_t *next_snapid,
 			 unsigned long *right_nr,  unsigned long *deleted_nr,
-			 unsigned int *nr_copies)
+			 unsigned int *nr_copies, uint64_t *ctime)
 {
 	int ret;
 	unsigned long nr, start_nr;
@@ -244,7 +246,7 @@ static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
 	right_side:
 		/* look up on the right side of the hash point */
 		ret = find_first_vdi(epoch, nr - 1, start_nr, name, tag, snapid, vid,
-				     deleted_nr, next_snapid, nr_copies);
+				     deleted_nr, next_snapid, nr_copies, ctime);
 		return ret;
 	} else {
 		/* round up... bitmap search from the head of the bitmap */
@@ -255,7 +257,7 @@ static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
 		else if (nr) {
 			/* look up on the left side of the hash point */
 			ret = find_first_vdi(epoch, nr - 1, 0, name, tag, snapid, vid,
-					     deleted_nr, next_snapid, nr_copies);
+					     deleted_nr, next_snapid, nr_copies, ctime);
 			if (ret == SD_RES_NO_VDI)
 				; /* we need to go to the right side */
 			else
@@ -268,7 +270,7 @@ static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
 }
 
 int lookup_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
-	       uint32_t snapid, unsigned int *nr_copies)
+	       uint32_t snapid, unsigned int *nr_copies, uint64_t *ctime)
 {
 	char *name = data, *tag;
 	uint32_t dummy0;
@@ -282,7 +284,7 @@ int lookup_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
 		return SD_RES_INVALID_PARMS;
 
 	return do_lookup_vdi(epoch, name, strlen(name), vid, tag, snapid,
-			     &dummy0, &dummy1, &dummy2, nr_copies);
+			     &dummy0, &dummy1, &dummy2, nr_copies, ctime);
 }
 
 int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
@@ -301,7 +303,7 @@ int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
 	name = data;
 
 	ret = do_lookup_vdi(epoch, name, strlen(name), &cur_vid, NULL, 0, &next_snapid,
-			    &right_nr, &deleted_nr, nr_copies);
+			    &right_nr, &deleted_nr, nr_copies, NULL);
 
 	if (is_snapshot) {
 		if (ret != SD_RES_SUCCESS) {
@@ -375,7 +377,7 @@ int del_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
 	}
 
 	ret = do_lookup_vdi(epoch, name, strlen(name), vid, tag, snapid,
-			    &dummy0, &dummy1, &dummy2, nr_copies);
+			    &dummy0, &dummy1, &dummy2, nr_copies, NULL);
 	if (ret != SD_RES_SUCCESS)
 		goto out;
 
@@ -658,11 +660,12 @@ err:
 	return ret;
 }
 
-int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
-		 uint32_t *attrid, int copies, int creat, int excl)
+int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
+		 uint32_t vid, uint32_t *attrid, int copies, uint64_t ctime,
+		 int creat, int excl)
 {
 	struct sheepdog_vnode_list_entry *entries;
-	char attr_buf[SD_ATTR_HEADER_SIZE];
+	struct sheepdog_vdi_attr tmp_attr;
 	uint64_t oid;
 	uint32_t end;
 	int ret, nr_zones, nr_vnodes;
@@ -679,20 +682,22 @@ int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
 		goto out;
 	}
 
+	vattr->ctime = ctime;
+
 	get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
 
-	*attrid = fnv_64a_buf(data, data_len, FNV1A_64_INIT);
+	*attrid = fnv_64a_buf(vattr, data_len, FNV1A_64_INIT);
 	*attrid &= (UINT64_C(1) << VDI_SPACE_SHIFT) - 1;
 
 	end = *attrid - 1;
 	while (*attrid != end) {
 		oid = vid_to_attr_oid(vid, *attrid);
-		ret = read_object(entries, nr_vnodes, nr_zones, epoch, oid, attr_buf,
-				  sizeof(attr_buf), 0, copies);
+		ret = read_object(entries, nr_vnodes, nr_zones, epoch, oid, (char *)&tmp_attr,
+				  sizeof(tmp_attr), 0, copies);
 
 		if (ret == -SD_RES_NO_OBJ && creat) {
-			ret = write_object(entries, nr_vnodes, nr_zones, epoch, oid, data,
-					   data_len, 0, copies, 1);
+			ret = write_object(entries, nr_vnodes, nr_zones, epoch, oid,
+					   (char *)vattr, data_len, 0, copies, 1);
 			if (ret)
 				ret = SD_RES_EIO;
 			else
@@ -703,7 +708,7 @@ int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
 		if (ret < 0)
 			return -ret;
 
-		if (memcmp(attr_buf, data, sizeof(attr_buf)) == 0) {
+		if (memcmp(&tmp_attr, vattr, sizeof(tmp_attr)) == 0) {
 			if (excl)
 				ret = SD_RES_VDI_EXIST;
 			else
-- 
1.7.2.5




More information about the sheepdog mailing list