[Sheepdog] [PATCH 1/2] reduce the maximum size of vdi attributes from 4 MB to 64 KB

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Fri Nov 18 11:43:36 CET 2011


This allows us to make simple_store_read()/write() fail when it cannot
read/write full length data.

This patch can also remove SD_FLAG_CMD_TRUNCATE.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/vdi.c             |   47 +++++++++++++++++++--------------------------
 include/sheepdog_proto.h |    9 +++----
 sheep/simple_store.c     |    9 --------
 sheep/vdi.c              |   24 +++++++++++++---------
 4 files changed, 38 insertions(+), 51 deletions(-)

diff --git a/collie/vdi.c b/collie/vdi.c
index c624131..d9f8bdb 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -792,18 +792,16 @@ 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;
-	struct sheepdog_vdi_attr *vattr;
+	struct sheepdog_vdi_attr vattr;
 
-	vattr = zalloc(SD_ATTR_HEADER_SIZE + value_len);
-	if (!vattr)
-		return SD_RES_NO_MEM;
-
-	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);
-	if (value && value_len)
-		memcpy(vattr->value, value, value_len);
+	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);
+	if (value && value_len) {
+		vattr.value_len = value_len;
+		memcpy(vattr.value, value, value_len);
+	}
 
 	fd = connect_to(sdhost, sdport);
 	if (fd < 0) {
@@ -813,7 +811,7 @@ static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
 
 	memset(&hdr, 0, sizeof(hdr));
 	hdr.opcode = SD_OP_GET_VDI_ATTR;
-	wlen = SD_ATTR_HEADER_SIZE + value_len;
+	wlen = SD_ATTR_OBJ_SIZE;
 	rlen = 0;
 	hdr.proto_ver = SD_PROTO_VER;
 	hdr.data_length = wlen;
@@ -826,7 +824,7 @@ static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
 	if (delete)
 		hdr.flags |= SD_FLAG_CMD_DEL;
 
-	ret = exec_req(fd, (struct sd_req *)&hdr, vattr, &wlen, &rlen);
+	ret = exec_req(fd, (struct sd_req *)&hdr, &vattr, &wlen, &rlen);
 	if (ret) {
 		ret = SD_RES_EIO;
 		goto out;
@@ -915,7 +913,8 @@ static int vdi_getattr(int argc, char **argv)
 	int ret;
 	uint64_t oid, attr_oid = 0;
 	uint32_t vid = 0, nr_copies = 0;
-	char *vdiname = argv[optind++], *key, *value;
+	char *vdiname = argv[optind++], *key;
+	struct sheepdog_vdi_attr vattr;
 
 	key = argv[optind++];
 	if (!key) {
@@ -939,22 +938,16 @@ static int vdi_getattr(int argc, char **argv)
 	}
 
 	oid = attr_oid;
-	value = malloc(SD_MAX_VDI_ATTR_VALUE_LEN);
-	if (!value) {
-		fprintf(stderr, "failed to allocate memory\n");
-		return EXIT_SYSFAIL;
-	}
 
-	ret = sd_read_object(oid, value, SD_MAX_VDI_ATTR_VALUE_LEN,
-			     SD_ATTR_HEADER_SIZE);
-	if (ret == SD_RES_SUCCESS) {
-		printf("%s", value);
-		free(value);
-		return EXIT_SUCCESS;
+	ret = sd_read_object(oid, &vattr, SD_ATTR_OBJ_SIZE, 0);
+	if (ret != SD_RES_SUCCESS) {
+		fprintf(stderr, "failed to read attr oid, %s\n",
+			sd_strerror(ret));
+		return EXIT_SYSFAIL;
 	}
 
-	free(value);
-	return EXIT_FAILURE;
+	xwrite(STDOUT_FILENO, vattr.value, vattr.value_len);
+	return EXIT_SUCCESS;
 }
 
 static int vdi_read(int argc, char **argv)
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 198ccdc..fc667b6 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -31,7 +31,6 @@
 
 #define SD_FLAG_CMD_WRITE    0x01
 #define SD_FLAG_CMD_COW      0x02
-#define SD_FLAG_CMD_TRUNCATE 0x04
 
 #define SD_RES_SUCCESS       0x00 /* Success */
 #define SD_RES_UNKNOWN       0x01 /* Unknown error */
@@ -80,7 +79,7 @@
 #define SD_MAX_VDI_LEN 256U
 #define SD_MAX_VDI_TAG_LEN 256U
 #define SD_MAX_VDI_ATTR_KEY_LEN 256U
-#define SD_MAX_VDI_ATTR_VALUE_LEN (UINT64_C(1) << 22)
+#define SD_MAX_VDI_ATTR_VALUE_LEN 65536U
 #define SD_NR_VDIS   (1U << 24)
 #define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
 #define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
@@ -89,7 +88,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 (sizeof(struct sheepdog_vdi_attr))
+#define SD_ATTR_OBJ_SIZE (sizeof(struct sheepdog_vdi_attr))
 #define CURRENT_VDI_ID 0
 
 struct sd_req {
@@ -191,9 +190,9 @@ struct sheepdog_vdi_attr {
 	char tag[SD_MAX_VDI_TAG_LEN];
 	uint64_t ctime;
 	uint32_t snap_id;
-	uint32_t pad;
+	uint32_t value_len;
 	char key[SD_MAX_VDI_ATTR_KEY_LEN];
-	char value[0];
+	char value[SD_MAX_VDI_ATTR_VALUE_LEN];
 };
 
 /*
diff --git a/sheep/simple_store.c b/sheep/simple_store.c
index 1e3a8fc..59d0a8a 100644
--- a/sheep/simple_store.c
+++ b/sheep/simple_store.c
@@ -106,15 +106,6 @@ static int simple_store_open(uint64_t oid, struct siocb *iocb, int create)
 			}
 		}
 	}
-	if (iocb->flags & SD_FLAG_CMD_TRUNCATE) {
-		ret = ftruncate(iocb->fd, iocb->offset + iocb->length);
-		if (ret) {
-			eprintf("%m\n");
-			ret = SD_RES_EIO;
-			close(iocb->fd);
-			goto out;
-		}
-	}
 
 	ret = SD_RES_SUCCESS;
 out:
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 5c3ac9a..3d36d89 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -655,12 +655,9 @@ int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
 {
 	struct sheepdog_vnode_list_entry *entries = NULL;
 	struct sheepdog_vdi_attr tmp_attr;
-	uint64_t oid;
+	uint64_t oid, hval;
 	uint32_t end;
 	int ret, nr_zones, nr_vnodes;
-	int value_len;
-
-	value_len = data_len - SD_ATTR_HEADER_SIZE;
 
 	vattr->ctime = ctime;
 
@@ -668,8 +665,12 @@ int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
 	if (ret != SD_RES_SUCCESS)
 		goto out;
 
-	*attrid = fnv_64a_buf(vattr, SD_ATTR_HEADER_SIZE, FNV1A_64_INIT);
-	*attrid &= (UINT64_C(1) << VDI_SPACE_SHIFT) - 1;
+	/* we cannot include value_len for calculating the hash value */
+	hval = fnv_64a_buf(vattr->name, sizeof(vattr->name), FNV1A_64_INIT);
+	hval = fnv_64a_buf(vattr->tag, sizeof(vattr->tag), hval);
+	hval = fnv_64a_buf(&vattr->snap_id, sizeof(vattr->snap_id), hval);
+	hval = fnv_64a_buf(vattr->key, sizeof(vattr->key), hval);
+	*attrid = hval & ((UINT64_C(1) << VDI_SPACE_SHIFT) - 1);
 
 	end = *attrid - 1;
 	while (*attrid != end) {
@@ -690,7 +691,11 @@ int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
 		if (ret < 0)
 			return -ret;
 
-		if (memcmp(&tmp_attr, vattr, sizeof(tmp_attr)) == 0) {
+		/* compare attribute header */
+		if (strcmp(tmp_attr.name, vattr->name) == 0 &&
+		    strcmp(tmp_attr.tag, vattr->tag) == 0 &&
+		    tmp_attr.snap_id == vattr->snap_id &&
+		    strcmp(tmp_attr.key, vattr->key) == 0) {
 			if (excl)
 				ret = SD_RES_VDI_EXIST;
 			else if (delete) {
@@ -704,9 +709,8 @@ int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
 					ret = SD_RES_SUCCESS;
 			} else if (write) {
 				ret = write_object(entries, nr_vnodes, nr_zones,
-						   epoch, oid, vattr->value,
-						   value_len, SD_ATTR_HEADER_SIZE,
-						   SD_FLAG_CMD_TRUNCATE, copies, 0);
+						   epoch, oid, (char *)vattr,
+						   SD_ATTR_OBJ_SIZE, 0, 0, copies, 0);
 
 				if (ret)
 					ret = SD_RES_EIO;
-- 
1.7.2.5




More information about the sheepdog mailing list