<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2014-02-27 13:48 GMT+08:00 Liu Yuan <span dir="ltr"><<a href="mailto:namei.unix@gmail.com" target="_blank">namei.unix@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Add a SD_OP_EXIST to check if an object exists in the specific node.<br>
<br>
Signed-off-by: Liu Yuan <<a href="mailto:namei.unix@gmail.com">namei.unix@gmail.com</a>><br>
---<br>
 dog/vdi.c                | 275 +++++++++++++----------------------------------<br>
 include/internal_proto.h |   1 +<br>
 sheep/ops.c              |  20 ++++<br>
 sheep/recovery.c         |  17 +--<br>
 sheep/sheep_priv.h       |   1 +<br>
 5 files changed, 106 insertions(+), 208 deletions(-)<br>
<br>
diff --git a/dog/vdi.c b/dog/vdi.c<br>
index debed0a..8a8f089 100644<br>
--- a/dog/vdi.c<br>
+++ b/dog/vdi.c<br>
@@ -210,122 +210,23 @@ static void print_vdi_graph(uint32_t vid, const char *name, const char *tag,<br>
<br>
 }<br>
<br>
-static void vdi_info_filler(uint32_t vid, const char *name, const char *tag,<br>
-                           uint32_t snapid, uint32_t flags,<br>
-                           const struct sd_inode *i, void *data)<br>
-{<br>
-       struct get_vdi_info *info = data;<br>
-<br>
-       if (info->name) {<br>
-               if (info->tag && info->tag[0]) {<br>
-                       if (!strcmp(name, info->name) &&<br>
-                           !strcmp(tag, info->tag)) {<br>
-                               info->vid = vid;<br>
-                       info->nr_copies = i->nr_copies;<br>
-                       info->copy_policy = i->copy_policy;<br>
-                       }<br>
-               } else if (info->snapid) {<br>
-                       if (!strcmp(name, info->name) &&<br>
-                           snapid == info->snapid) {<br>
-                               info->vid = vid;<br>
-                               info->nr_copies = i->nr_copies;<br>
-                               info->copy_policy = i->copy_policy;<br>
-                       }<br>
-               } else {<br>
-                       if (!strcmp(name, info->name)) {<br>
-                               info->vid = vid;<br>
-                               info->nr_copies = i->nr_copies;<br>
-                               info->copy_policy = i->copy_policy;<br>
-                       }<br>
-               }<br>
-       }<br>
-}<br>
-<br>
-typedef int (*obj_parser_func_t)(const char *sheep, uint64_t oid,<br>
-                                struct sd_rsp *rsp, char *buf, void *data);<br>
-<br>
-static int do_print_obj(const char *sheep, uint64_t oid, struct sd_rsp *rsp,<br>
-                       char *buf, void *data)<br>
-{<br>
-       switch (rsp->result) {<br>
-       case SD_RES_SUCCESS:<br>
-               printf("%s has the object\n", sheep);<br>
-               break;<br>
-       case SD_RES_NO_OBJ:<br>
-               printf("%s doesn't have the object\n", sheep);<br>
-               break;<br>
-       case SD_RES_OLD_NODE_VER:<br>
-       case SD_RES_NEW_NODE_VER:<br>
-               sd_err("The node list has changed: please try again");<br>
-               break;<br>
-       default:<br>
-               sd_err("%s: hit an unexpected error (%s)", sheep,<br>
-                      sd_strerror(rsp->result));<br>
-               break;<br>
-       }<br>
-<br>
-       return 0;<br>
-}<br>
-<br>
-struct obj_info_filler_info {<br>
-       bool success;<br>
-       uint64_t data_oid;<br>
-       unsigned idx;<br>
-};<br>
-<br>
-static int obj_info_filler(const char *sheep, uint64_t oid, struct sd_rsp *rsp,<br>
-                          char *buf, void *data)<br>
+static void for_each_node_print(uint64_t oid)<br>
 {<br>
-       struct obj_info_filler_info *info = data;<br>
-       struct sd_inode *inode = (struct sd_inode *)buf;<br>
-       uint32_t vdi_id;<br>
-<br>
-       switch (rsp->result) {<br>
-       case SD_RES_SUCCESS:<br>
-               if (info->success)<br>
-                       break;<br>
-               info->success = true;<br>
-               vdi_id = sd_inode_get_vid(inode, info->idx);<br>
-               if (vdi_id) {<br>
-                       info->data_oid = vid_to_data_oid(vdi_id, info->idx);<br>
-                       return 1;<br>
-               }<br>
-               break;<br>
-       case SD_RES_NO_OBJ:<br>
-               break;<br>
-       case SD_RES_OLD_NODE_VER:<br>
-       case SD_RES_NEW_NODE_VER:<br>
-               sd_err("The node list has changed: please try again");<br>
-               break;<br>
-       default:<br>
-               sd_err("%s: hit an unexpected error (%s)", sheep,<br>
-                      sd_strerror(rsp->result));<br>
-               break;<br>
-       }<br>
-<br>
-       return 0;<br>
-}<br>
-<br>
-static void parse_objs(uint64_t oid, obj_parser_func_t func, void *data,<br>
-                      size_t size)<br>
-{<br>
-       int ret, cb_ret;<br>
+       int ret;<br>
        struct sd_node *n;<br>
-       char *buf;<br>
+       const char *sheep;<br>
<br>
-       buf = xzalloc(size);<br>
        rb_for_each_entry(n, &sd_nroot, rb) {<br>
                struct sd_req hdr;<br>
                struct sd_rsp *rsp = (struct sd_rsp *)&hdr;<br>
<br>
-               sd_init_req(&hdr, SD_OP_READ_PEER);<br>
-               hdr.data_length = size;<br>
+               sd_init_req(&hdr, SD_OP_EXIST);<br>
+               hdr.data_length = 0;<br>
                hdr.flags = 0;<br>
                hdr.epoch = sd_epoch;<br>
                hdr.obj.oid = oid;<br>
-               hdr.obj.ec_index = SD_MAX_COPIES + 1; /* Ignore index */<br>
<br>
-               ret = dog_exec_req(&n->nid, &hdr, buf);<br>
+               ret = dog_exec_req(&n->nid, &hdr, NULL);<br>
                if (ret < 0)<br>
                        continue;<br>
                switch (rsp->result) {<br>
@@ -333,16 +234,26 @@ static void parse_objs(uint64_t oid, obj_parser_func_t func, void *data,<br>
                        continue;<br>
                }<br>
<br>
-               cb_ret = func(addr_to_str(n->nid.addr, n->nid.port),<br>
-                             oid, rsp, buf, data);<br>
-               if (cb_ret)<br>
+               sheep = addr_to_str(n->nid.addr, n->nid.port);<br>
+               switch (rsp->result) {<br>
+               case SD_RES_SUCCESS:<br>
+                       printf("%s has the object\n", sheep);<br>
+                       break;<br>
+               case SD_RES_NO_OBJ:<br>
+                       printf("%s doesn't have the object\n", sheep);<br>
                        break;<br>
+               case SD_RES_OLD_NODE_VER:<br>
+               case SD_RES_NEW_NODE_VER:<br>
+                       sd_err("The node list has changed: please try again");<br>
+                       break;<br>
+               default:<br>
+                       sd_err("%s: hit an unexpected error (%s)", sheep,<br>
+                              sd_strerror(rsp->result));<br>
+                       break;<br>
+               }<br>
        }<br>
-<br>
-       free(buf);<br>
 }<br>
<br>
-<br>
 static int vdi_list(int argc, char **argv)<br>
 {<br>
        const char *vdiname = argv[optind];<br>
@@ -901,67 +812,52 @@ static int vdi_object_map(int argc, char **argv)<br>
 static int vdi_object_location(int argc, char **argv)<br>
 {<br>
        const char *vdiname = argv[optind];<br>
-       uint64_t idx = vdi_cmd_data.index;<br>
-       struct get_vdi_info info;<br>
-       uint32_t vid;<br>
-       size_t size;<br>
-<br>
-       memset(&info, 0, sizeof(info));<br>
-       <a href="http://info.name" target="_blank">info.name</a> = vdiname;<br>
-       info.tag = vdi_cmd_data.snapshot_tag;<br>
-       info.vid = 0;<br>
-       info.snapid = vdi_cmd_data.snapshot_id;<br>
-<br>
-       if (parse_vdi(vdi_info_filler, SD_INODE_HEADER_SIZE, &info) < 0)<br>
-               return EXIT_SYSFAIL;<br>
+       uint64_t idx = vdi_cmd_data.index, oid;<br>
+       struct sd_inode *inode = xmalloc(sizeof(*inode));<br>
+       uint32_t vid, vdi_id;<br>
+       int ret;<br>
<br>
-       vid = info.vid;<br>
-       if (vid == 0) {<br>
-               sd_err("VDI not found");<br>
-               return EXIT_MISSING;<br>
+       ret = read_vdi_obj(vdiname, vdi_cmd_data.snapshot_id,<br>
+                          vdi_cmd_data.snapshot_tag, NULL, inode,<br>
+                          SD_INODE_SIZE);<br>
+       if (ret != EXIT_SUCCESS) {<br>
+               sd_err("FATAL: no inode objects");<br>
+               return ret;<br></blockquote><div><br></div><div>May be we should use 'goto out' which will free the memory of inode.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

        }<br>
+       vid = inode->vdi_id;<br>
<br>
        if (idx == ~0) {<br>
-               printf("Looking for the inode object 0x%" PRIx32 " with %d nodes\n\n",<br>
+               printf("Looking for the inode object 0x%" PRIx32 " with %d"<br>
+                      " nodes\n\n",<br>
                       vid, sd_nodes_nr);<br>
-               parse_objs(vid_to_vdi_oid(vid), do_print_obj, NULL,<br>
-                          SD_INODE_SIZE);<br>
-       } else {<br>
-               struct obj_info_filler_info oid_info = {0};<br>
+               for_each_node_print(vid_to_vdi_oid(vid));<br>
+               ret = EXIT_SUCCESS;<br>
+               goto out;<br>
+       }<br>
<br>
-               oid_info.success = false;<br>
-               oid_info.idx = idx;<br>
+       if (idx >= MAX_DATA_OBJS) {<br>
+               printf("The offset is too large!\n");<br>
+               ret = EXIT_FAILURE;<br>
+               goto out;<br>
+       }<br>
<br>
-               if (idx >= MAX_DATA_OBJS) {<br>
-                       printf("The offset is too large!\n");<br>
-                       exit(EXIT_FAILURE);<br>
-               }<br>
+       vdi_id = sd_inode_get_vid(inode, idx);<br>
+       oid = vid_to_data_oid(vdi_id, idx);<br>
+       if (vdi_id) {<br>
+               printf("Looking for the object 0x%" PRIx64<br>
+                      " (vid 0x%" PRIx32 " idx %"PRIu64<br>
+                      ", %u copies) with %d nodes\n\n",<br>
+                       oid, vid, idx, inode->nr_copies, sd_nodes_nr);<br>
<br>
-               size = get_store_objsize(info.copy_policy,<br>
-                                        vid_to_data_oid(vid, 0));<br>
-               parse_objs(vid_to_vdi_oid(vid), obj_info_filler, &oid_info,<br>
-                          size);<br>
-<br>
-               if (oid_info.success) {<br>
-                       if (oid_info.data_oid) {<br>
-                               printf("Looking for the object 0x%" PRIx64<br>
-                                      " (vid 0x%" PRIx32 " idx %"PRIu64<br>
-                                      ", %u copies) with %d nodes\n\n",<br>
-                                      oid_info.data_oid, vid, idx,<br>
-                                      info.nr_copies, sd_nodes_nr);<br>
-<br>
-                               parse_objs(oid_info.data_oid, do_print_obj,<br>
-                                          NULL, size);<br>
-                       } else<br>
-                               printf("The inode object 0x%" PRIx32 " idx"<br>
-                                      " %"PRIu64" is not allocated\n",<br>
-                                      vid, idx);<br>
-               } else<br>
-                       sd_err("Failed to read the inode object 0x%" PRIx32,<br>
-                              vid);<br>
-       }<br>
+               for_each_node_print(oid);<br>
+       } else<br>
+               printf("The inode object 0x%" PRIx32 " idx"<br>
+                      " %"PRIu64" is not allocated\n",<br>
+                      vid, idx);<br>
<br>
-       return EXIT_SUCCESS;<br>
+out:<br>
+       free(inode);<br>
+       return ret;<br>
 }<br>
<br>
 static int do_track_object(uint64_t oid, uint8_t nr_copies)<br>
@@ -1032,59 +928,37 @@ static int vdi_track(int argc, char **argv)<br>
 {<br>
        const char *vdiname = argv[optind];<br>
        unsigned idx = vdi_cmd_data.index;<br>
-       struct get_vdi_info info;<br>
-       struct obj_info_filler_info oid_info = {0};<br>
-       uint32_t vid;<br>
        uint8_t nr_copies;<br>
        uint64_t oid = vdi_cmd_data.oid;<br>
+       struct sd_inode *inode = xmalloc(sizeof(*inode));<br>
+       uint32_t vid, vdi_id;<br>
+       int ret;<br>
<br>
-       memset(&info, 0, sizeof(info));<br>
-       <a href="http://info.name" target="_blank">info.name</a> = vdiname;<br>
-       info.tag = vdi_cmd_data.snapshot_tag;<br>
-       info.vid = 0;<br>
-       info.snapid = vdi_cmd_data.snapshot_id;<br>
-<br>
-       if (parse_vdi(vdi_info_filler, SD_INODE_HEADER_SIZE, &info) < 0)<br>
-               return EXIT_SYSFAIL;<br>
-<br>
-       vid = info.vid;<br>
-       nr_copies = info.nr_copies;<br>
-       if (vid == 0) {<br>
-               sd_err("VDI not found");<br>
-               return EXIT_MISSING;<br>
+       ret = read_vdi_obj(vdiname, vdi_cmd_data.snapshot_id,<br>
+                          vdi_cmd_data.snapshot_tag, NULL, inode,<br>
+                          SD_INODE_SIZE);<br>
+       if (ret != EXIT_SUCCESS) {<br>
+               sd_err("FATAL: no inode objects");<br>
+               return ret;<br></blockquote><div><br></div><div>ditto</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
        }<br>
+       vid = inode->vdi_id;<br>
+       nr_copies = inode->nr_copies;<br>
<br>
        if (!oid) {<br>
                if (idx == ~0) {<br>
                        printf("Tracking the inode object 0x%" PRIx32<br>
                               " with %d nodes\n", vid, sd_nodes_nr);<br>
+                       free(inode);<br>
                        return do_track_object(vid_to_vdi_oid(vid), nr_copies);<br>
                }<br>
<br>
-               oid_info.success = false;<br>
-               oid_info.idx = idx;<br>
-<br>
                if (idx >= MAX_DATA_OBJS) {<br>
                        printf("The offset is too large!\n");<br>
                        goto err;<br>
                }<br>
<br>
-               parse_objs(vid_to_vdi_oid(vid), obj_info_filler, &oid_info,<br>
-                          get_store_objsize(info.copy_policy,<br>
-                                            vid_to_data_oid(vid, 0)));<br>
-<br>
-               if (!oid_info.success) {<br>
-                       sd_err("Failed to read the inode object 0x%" PRIx32,<br>
-                              vid);<br>
-                       goto err;<br>
-               }<br>
-               if (!oid_info.data_oid) {<br>
-                       printf("The inode object 0x%"PRIx32<br>
-                              " idx %u is not allocated\n", vid, idx);<br>
-                       goto err;<br>
-               }<br>
-<br>
-               oid = oid_info.data_oid;<br>
+               vdi_id = sd_inode_get_vid(inode, idx);<br>
+               oid = vid_to_data_oid(vdi_id, idx);<br>
<br>
                printf("Tracking the object 0x%" PRIx64<br>
                       " (the inode vid 0x%" PRIx32 " idx %u)"<br>
@@ -1094,9 +968,10 @@ static int vdi_track(int argc, char **argv)<br>
                       " (the inode vid 0x%" PRIx32 ")"<br>
                       " with %d nodes\n", oid, vid, sd_nodes_nr);<br>
<br>
+       free(inode);<br>
        return do_track_object(oid, nr_copies);<br>
-<br>
 err:<br>
+       free(inode);<br>
        return EXIT_FAILURE;<br>
 }<br>
<br>
diff --git a/include/internal_proto.h b/include/internal_proto.h<br>
index 460264c..ace4ac5 100644<br>
--- a/include/internal_proto.h<br>
+++ b/include/internal_proto.h<br>
@@ -99,6 +99,7 @@<br>
 #define SD_OP_SET_LOGLEVEL     0xBA<br>
 #define SD_OP_NFS_CREATE       0xBB<br>
 #define SD_OP_NFS_DELETE       0xBC<br>
+#define SD_OP_EXIST    0xBD<br>
<br>
 /* internal flags for hdr.flags, must be above 0x80 */<br>
 #define SD_FLAG_CMD_RECOVERY 0x0080<br>
diff --git a/sheep/ops.c b/sheep/ops.c<br>
index 0e9bc82..ca00a18 100644<br>
--- a/sheep/ops.c<br>
+++ b/sheep/ops.c<br>
@@ -1015,6 +1015,19 @@ static int local_set_loglevel(struct request *req)<br>
        return SD_RES_SUCCESS;<br>
 }<br>
<br>
+static int local_oid_exist(struct request *req)<br>
+{<br>
+       uint64_t oid = req->rq.obj.oid;<br>
+       uint8_t ec_index = local_ec_index(req->vinfo, oid);<br>
+<br>
+       if (is_erasure_oid(oid) && ec_index == SD_MAX_COPIES)<br>
+               return SD_RES_NO_OBJ;<br>
+<br>
+       if (sd_store->exist(oid, ec_index))<br>
+               return SD_RES_SUCCESS;<br>
+       return SD_RES_NO_OBJ;<br>
+}<br>
+<br>
 #ifdef HAVE_NFS<br>
<br>
 static int local_nfs_create(struct request *req)<br>
@@ -1336,6 +1349,13 @@ static struct sd_op_template sd_ops[] = {<br>
                .process_work = local_set_loglevel,<br>
        },<br>
<br>
+       [SD_OP_EXIST] =  {<br>
+               .name = "EXIST",<br>
+               .type = SD_OP_TYPE_LOCAL,<br>
+               .force = true,<br>
+               .process_work = local_oid_exist,<br>
+       },<br>
+<br>
 #ifdef HAVE_NFS<br>
        [SD_OP_NFS_CREATE] = {<br>
                .name = "NFS_CREATE",<br>
diff --git a/sheep/recovery.c b/sheep/recovery.c<br>
index 1e5f1af..859375d 100644<br>
--- a/sheep/recovery.c<br>
+++ b/sheep/recovery.c<br>
@@ -445,19 +445,20 @@ out:<br>
        return lost;<br>
 }<br>
<br>
-static uint8_t local_node_copy_index(struct vnode_info *vinfo, uint64_t oid)<br>
+uint8_t local_ec_index(struct vnode_info *vinfo, uint64_t oid)<br>
 {<br>
-       int idx;<br>
+       int idx, m = min(get_vdi_copy_number(oid_to_vid(oid)), vinfo->nr_zones);<br>
<br>
        if (!is_erasure_oid(oid))<br>
-               return 0; /* no need to proceed */<br>
+               return SD_MAX_COPIES;<br>
<br>
-       for (idx = 0; idx < vinfo->nr_zones; idx++) {<br>
+       for (idx = 0; idx < m; idx++) {<br>
                const struct sd_node *n = oid_to_node(oid, &vinfo->vroot, idx);<br>
                if (node_is_local(n))<br>
                        return idx;<br>
        }<br>
-       panic("can't get valid index for %"PRIx64, oid);<br>
+       sd_debug("can't get valid index for %"PRIx64, oid);<br>
+       return SD_MAX_COPIES;<br>
 }<br>
<br>
 /*<br>
@@ -486,7 +487,7 @@ static int recover_erasure_object(struct recovery_obj_work *row)<br>
        uint8_t idx;<br>
        int ret = -1;<br>
<br>
-       idx = local_node_copy_index(cur, oid);<br>
+       idx = local_ec_index(cur, oid);<br>
        buf = read_erasure_object(oid, idx, row);<br>
        if (!buf && !row->stop)<br>
                buf = rebuild_erasure_object(oid, idx, row);<br>
@@ -530,7 +531,7 @@ static void recover_object_work(struct work *work)<br>
        struct vnode_info *cur = rw->cur_vinfo;<br>
        int ret, epoch;<br>
<br>
-       if (sd_store->exist(oid, local_node_copy_index(cur, oid))) {<br>
+       if (sd_store->exist(oid, local_ec_index(cur, oid))) {<br>
                sd_debug("the object is already recovered");<br>
                return;<br>
        }<br>
@@ -585,7 +586,7 @@ main_fn bool oid_in_recovery(uint64_t oid)<br>
                return false;<br>
<br>
        cur = rinfo->cur_vinfo;<br>
-       if (sd_store->exist(oid, local_node_copy_index(cur, oid))) {<br>
+       if (sd_store->exist(oid, local_ec_index(cur, oid))) {<br>
                sd_debug("the object %" PRIx64 " is already recoverd", oid);<br>
                return false;<br>
        }<br>
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h<br>
index f9c5062..3737f5a 100644<br>
--- a/sheep/sheep_priv.h<br>
+++ b/sheep/sheep_priv.h<br>
@@ -436,6 +436,7 @@ int gateway_write_obj(struct request *req);<br>
 int gateway_create_and_write_obj(struct request *req);<br>
 int gateway_remove_obj(struct request *req);<br>
 bool is_erasure_oid(uint64_t oid);<br>
+uint8_t local_ec_index(struct vnode_info *vinfo, uint64_t oid);<br>
<br>
 /* object_cache */<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.8.1.2<br>
<br>
--<br>
sheepdog mailing list<br>
<a href="mailto:sheepdog@lists.wpkg.org">sheepdog@lists.wpkg.org</a><br>
<a href="http://lists.wpkg.org/mailman/listinfo/sheepdog" target="_blank">http://lists.wpkg.org/mailman/listinfo/sheepdog</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br>--<br>Best Regard<br>Robin Dong
</div></div>