[Sheepdog] [PATCH v2] collie: avoid reading entire vdi object

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Tue Feb 1 17:30:48 CET 2011


This improves performance of some collie commands significantly.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
The previous patch is not correct because vdi_list() uses a data oid
field.

 collie/collie.c          |   60 +++++++++++++++++++++++++++++++++++----------
 include/sheepdog_proto.h |    2 +
 2 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/collie/collie.c b/collie/collie.c
index 493d492..169f3d2 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -244,7 +244,7 @@ static int shutdown_sheepdog(void)
 typedef void (*vdi_parser_func_t)(uint32_t vid, char *name, uint32_t tag, uint32_t flags,
 				  struct sheepdog_inode *i, void *data);
 
-static int parse_vdi(vdi_parser_func_t func, void *data)
+static int parse_vdi(vdi_parser_func_t func, size_t size, void *data)
 {
 	int ret, fd;
 	unsigned long nr;
@@ -293,7 +293,8 @@ static int parse_vdi(vdi_parser_func_t func, void *data)
 		}
 
 		wlen = 0;
-		rlen = sizeof(i);
+		rlen = SD_INODE_HEADER_SIZE;
+		memset(&i, 0, sizeof(i));
 
 		memset(&hdr, 0, sizeof(hdr));
 		hdr.opcode = SD_OP_READ_OBJ;
@@ -303,14 +304,45 @@ static int parse_vdi(vdi_parser_func_t func, void *data)
 		hdr.epoch = node_list_version;
 
 		ret = exec_req(fd, (struct sd_req *)&hdr, &i, &wlen, &rlen);
-		close(fd);
 
-		if (!ret && rsp->result == SD_RES_SUCCESS) {
-			if (i.name[0] == '\0') /* deleted */
-				continue;
-			func(i.vdi_id, i.name, i.snap_id, 0, &i, data);
-		} else
-			printf("error %lu, %d, %x\n", nr, ret, rsp->result);
+		if (ret || rsp->result != SD_RES_SUCCESS) {
+			printf("failed to read a inode header %lu, %d, %x\n",
+			       nr, ret, rsp->result);
+			goto next;
+		}
+
+		if (i.name[0] == '\0') /* this vdi is deleted */
+			goto next;
+
+		if (size > SD_INODE_HEADER_SIZE) {
+			wlen = 0;
+			rlen = DIV_ROUND_UP(i.vdi_size, SD_DATA_OBJ_SIZE) *
+				sizeof(i.data_vdi_id[0]);
+			if (rlen > size - SD_INODE_HEADER_SIZE)
+				rlen = size - SD_INODE_HEADER_SIZE;
+
+			memset(&hdr, 0, sizeof(hdr));
+			hdr.opcode = SD_OP_READ_OBJ;
+			hdr.oid = oid;
+			hdr.offset = SD_INODE_HEADER_SIZE;
+			hdr.data_length = rlen;
+			hdr.flags = SD_FLAG_CMD_DIRECT;
+			hdr.epoch = node_list_version;
+
+			ret = exec_req(fd, (struct sd_req *)&hdr,
+				       ((char *)&i) + SD_INODE_HEADER_SIZE,
+				       &wlen, &rlen);
+
+			if (ret || rsp->result != SD_RES_SUCCESS) {
+				printf("failed to read inode %lu, %d, %x\n",
+				       nr, ret, rsp->result);
+				goto next;
+			}
+		}
+
+		func(i.vdi_id, i.name, i.snap_id, 0, &i, data);
+	next:
+		close(fd);
 	}
 
 	return 0;
@@ -626,7 +658,7 @@ static int node_info(int argc, char **argv)
 		return 1;
 	}
 
-	parse_vdi(cal_total_vdi_size, &total_vdi_size);
+	parse_vdi(cal_total_vdi_size, SD_INODE_HEADER_SIZE, &total_vdi_size);
 
 	size_to_str(total_size, total_str, sizeof(total_str));
 	size_to_str(total_size - total_avail, avail_str, sizeof(avail_str));
@@ -650,14 +682,14 @@ static int vdi_list(int argc, char **argv)
 	printf("  name        id    size    used  shared    creation time   vdi id\n");
 	printf("------------------------------------------------------------------\n");
 
-	parse_vdi(print_vdi_list, NULL);
+	parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL);
 	return 0;
 }
 
 static int vdi_tree(int argc, char **argv)
 {
 	init_tree();
-	parse_vdi(print_vdi_tree, NULL);
+	parse_vdi(print_vdi_tree, SD_INODE_HEADER_SIZE, NULL);
 	dump_tree();
 
 	return 0;
@@ -670,7 +702,7 @@ static int vdi_graph(int argc, char **argv)
 	printf("  node [shape = \"box\", fontname = \"Courier\"];\n\n");
 	printf("  \"0\" [shape = \"ellipse\", label = \"root\"];\n\n");
 
-	parse_vdi(print_vdi_graph, NULL);
+	parse_vdi(print_vdi_graph, SD_INODE_HEADER_SIZE, NULL);
 
 	/* print a footer */
 	printf("}\n");
@@ -730,7 +762,7 @@ static int vdi_object(int argc, char **argv)
 	info.name = vdiname;
 	info.vid = 0;
 
-	ret = parse_vdi(get_oid, &info);
+	ret = parse_vdi(get_oid, SD_INODE_HEADER_SIZE, &info);
 
 	vid = info.vid;
 	if (vid == 0) {
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 0602ff5..6385c9a 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -79,6 +79,8 @@
 #define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
 
 #define SD_INODE_SIZE (sizeof(struct sheepdog_inode))
+#define SD_INODE_HEADER_SIZE (sizeof(struct sheepdog_inode) - \
+			      sizeof(uint32_t) * MAX_DATA_OBJS)
 #define CURRENT_VDI_ID 0
 
 struct sd_req {
-- 
1.5.6.5




More information about the sheepdog mailing list