<div dir="ltr">Reviewed-by: Robin Dong <<a href="mailto:sanbai@taobao.com">sanbai@taobao.com</a>></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/11/26 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 comment to it<br>
<br>
Signed-off-by: Liu Yuan <<a href="mailto:namei.unix@gmail.com">namei.unix@gmail.com</a>><br>
---<br>
 sheep/http/kv.c |   78 +++++++++++++++++++++++++++----------------------------<br>
 1 file changed, 38 insertions(+), 40 deletions(-)<br>
<br>
diff --git a/sheep/http/kv.c b/sheep/http/kv.c<br>
index 3770fdb..d30a6a1 100644<br>
--- a/sheep/http/kv.c<br>
+++ b/sheep/http/kv.c<br>
@@ -190,74 +190,72 @@ struct kv_object {<br>
        uint8_t data[SD_DATA_OBJ_SIZE - sizeof(struct kv_object_hdr)];<br>
 };<br>
<br>
+/*<br>
+ * Create the object if the index isn't taken. Overwrite the object if it exists<br>
+ * Return 0 if the index is taken by other object.<br>
+ */<br>
 static int do_kv_create_object(struct http_request *req, const char *obj_name,<br>
                               struct kv_object *obj, uint32_t vid,<br>
                               uint32_t idx)<br>
 {<br>
        uint64_t oid = vid_to_data_oid(vid, idx);<br>
+       uint32_t tmp_vid;<br>
        struct kv_object_hdr hdr;<br>
+       struct sd_inode *inode = xmalloc(sizeof(struct sd_inode));<br>
        int ret;<br>
<br>
-       ret = write_object(oid, (char *)obj, sizeof(obj->hdr) + obj->hdr.size,<br>
-                          0, true);<br>
-       if (ret != SD_RES_SUCCESS) {<br>
-               sd_err("failed to create object, %" PRIx64, oid);<br>
-               goto err;<br>
-       }<br>
-<br>
-       /*<br>
-        * XXX: SD_OP_CREATE_AND_WRITE_OBJ returns success even if the object<br>
-        * alreay exists.  We need to confirm that the stored object is actually<br>
-        * what we wrote.<br>
-        */<br>
-       ret = read_object(oid, (char *)&hdr, sizeof(hdr), 0);<br>
+       ret = read_object(vid_to_vdi_oid(vid), (char *)inode,<br>
+                         sizeof(*inode), 0);<br>
        if (ret != SD_RES_SUCCESS) {<br>
-               sd_err("failed to read object, %" PRIx64, oid);<br>
+               sd_err("failed to read inode, %" PRIx64,<br>
+                      vid_to_vdi_oid(vid));<br>
                goto err;<br>
        }<br>
+       tmp_vid = INODE_GET_VID(inode, idx);<br>
+       if (tmp_vid) {<br>
+               ret = read_object(oid, (char *)&hdr, sizeof(hdr), 0);<br>
+               if (ret != SD_RES_SUCCESS) {<br>
+                       sd_err("failed to read object, %" PRIx64, oid);<br>
+                       goto err;<br>
+               }<br>
<br>
-       if (<a href="http://hdr.name" target="_blank">hdr.name</a>[0] != '\0' && strcmp(<a href="http://hdr.name" target="_blank">hdr.name</a>, obj-><a href="http://hdr.name" target="_blank">hdr.name</a>) != 0) {<br>

-               sd_debug("index %d is already used", idx);<br>
-               return 0;<br>
-       }<br>
-<br>
-       if (memcmp(&hdr, &obj->hdr, sizeof(hdr)) == 0) {<br>
-               /* update inode object */<br>
-               struct sd_inode *inode = xmalloc(sizeof(struct sd_inode));<br>
-<br>
-               ret = read_object(vid_to_vdi_oid(vid), (char *)inode,<br>
-                                 sizeof(*inode), 0);<br>
+               if (<a href="http://hdr.name" target="_blank">hdr.name</a>[0] != '\0' &&<br>
+                   strcmp(<a href="http://hdr.name" target="_blank">hdr.name</a>, obj-><a href="http://hdr.name" target="_blank">hdr.name</a>) != 0){<br>
+                       sd_debug("index %d is already used", idx);<br>
+                       goto out;<br>
+               }<br>
+               sd_info("overwrite object %s", obj_name);<br>
+               ret = write_object(oid, (char *)obj,<br>
+                                  sizeof(obj->hdr) + obj->hdr.size,<br>
+                                  0, false);<br>
                if (ret != SD_RES_SUCCESS) {<br>
-                       sd_err("failed to read inode, %" PRIx64,<br>
-                              vid_to_vdi_oid(vid));<br>
-                       free(inode);<br>
+                       sd_err("failed to write object, %" PRIx64, oid);<br>
+                       goto err;<br>
+               }<br>
+       } else {<br>
+               ret = write_object(oid, (char *)obj,<br>
+                                  sizeof(obj->hdr) + obj->hdr.size,<br>
+                                  0, true);<br>
+               if (ret != SD_RES_SUCCESS) {<br>
+                       sd_err("failed to create object, %" PRIx64, oid);<br>
                        goto err;<br>
                }<br>
                INODE_SET_VID(inode, idx, vid);<br>
                ret = sd_inode_write_vid(sheep_bnode_writer, inode, idx,<br>
                                         vid, vid, 0, false, false);<br>
-               free(inode);<br>
                if (ret != SD_RES_SUCCESS) {<br>
                        sd_err("failed to update inode, %" PRIx64,<br>
                               vid_to_vdi_oid(vid));<br>
                        goto err;<br>
                }<br>
-       } else {<br>
-               sd_info("object %s already exists", obj_name);<br>
-<br>
-               /* write again without a create option */<br>
-               ret = write_object(oid, (char *)obj,<br>
-                                  sizeof(obj->hdr) + obj->hdr.size, 0, false);<br>
-               if (ret != SD_RES_SUCCESS) {<br>
-                       sd_err("failed to update object, %"PRIx64, oid);<br>
-                       goto err;<br>
-               }<br>
        }<br>
-<br>
        http_response_header(req, CREATED);<br>
+out:<br>
+       free(inode);<br>
        return 0;<br>
 err:<br>
        http_response_header(req, INTERNAL_SERVER_ERROR);<br>
+       free(inode);<br>
        return -1;<br>
 }<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.7.9.5<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>