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 |