<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/12/20 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">Also fix a API problem that return CONETENT_LENGTH for get operation<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    | 210 +++++++++++++++++++++++++----------------------------<br>
 sheep/http/swift.c |  12 ++-<br>
 2 files changed, 110 insertions(+), 112 deletions(-)<br>
<br>
diff --git a/sheep/http/kv.c b/sheep/http/kv.c<br>
index 0ba87a4..e5e1b6d 100644<br>
--- a/sheep/http/kv.c<br>
+++ b/sheep/http/kv.c<br>
@@ -29,7 +29,7 @@ struct bucket_inode_hdr {<br>
 struct bucket_inode {<br>
        union {<br>
                struct bucket_inode_hdr hdr;<br>
-               uint8_t data[SD_MAX_BUCKET_NAME << 1];<br>
+               uint8_t data[BLOCK_SIZE];<br>
        };<br>
 };<br>
<br>
@@ -814,18 +814,18 @@ struct find_object_arg {<br>
 };<br>
<br>
 static void find_object_cb(struct http_request *req, const char *bucket,<br>
-                          const char *object, void *opaque)<br>
+                          const char *name, void *opaque)<br>
 {<br>
        struct find_object_arg *foarg = (struct find_object_arg *)opaque;<br>
<br>
-       if (!strncmp(foarg->object_name, object, SD_MAX_OBJECT_NAME))<br>
+       if (!strncmp(foarg->object_name, name, SD_MAX_OBJECT_NAME))<br>
                foarg->found = true;<br>
 }<br>
<br>
 static bool kv_find_object(struct http_request *req, const char *account,<br>
-                          const char *bucket, const char *object)<br>
+                          const char *bucket, const char *name)<br>
 {<br>
-       struct find_object_arg arg = {false, object};<br>
+       struct find_object_arg arg = {false, name};<br>
        kv_list_objects(req, account, bucket, find_object_cb, &arg);<br>
        return arg.found;<br>
 }<br>
@@ -1059,6 +1059,82 @@ static int onode_free_data(struct kv_onode *onode)<br>
        return ret;<br>
 }<br>
<br>
+static int onode_read_extents(struct kv_onode *onode, struct http_request *req)<br>
+{<br>
+       struct onode_extent *ext;<br>
+       uint64_t size, total, total_size, offset, done = 0;<br>
+       uint32_t i;<br>
+       int ret;<br>
+       char *data_buf = NULL;<br>
+<br>
+       data_buf = xmalloc(READ_WRITE_BUFFER);<br>
+       total_size = onode->hdr.size;<br>
+       for (i = 0; i < onode->hdr.nr_extent; i++) {<br>
+               ext = onode->o_extent + i;<br>
+               total = min(ext->count * SD_DATA_OBJ_SIZE, total_size);<br>
+               offset = ext->start * SD_DATA_OBJ_SIZE;<br>
+               while (done < total) {<br>
+                       size = MIN(total - done, READ_WRITE_BUFFER);<br>
+                       ret = vdi_read_write(onode->hdr.data_vid, data_buf,<br>
+                                            size, offset, true);<br>
+                       if (ret != SD_RES_SUCCESS) {<br>
+                               sd_err("Failed to read for vid %"PRIx32,<br>
+                                      onode->hdr.data_vid);<br>
+                               goto out;<br>
+                       }<br>
+                       http_request_write(req, data_buf, size);<br>
+                       done += size;<br>
+                       offset += size;<br>
+                       total_size -= size;<br>
+               }<br>
+       }<br>
+out:<br>
+       free(data_buf);<br>
+       return ret;<br>
+}<br>
+<br>
+static int onode_lookup(struct kv_onode *onode, uint32_t onode_vid,<br>
+                       const char *name)<br>
+{<br>
+       uint64_t hval;<br>
+       uint32_t i;<br>
+       int ret;<br>
+<br>
+       sys->cdrv->lock(onode_vid);<br>
+       hval = sd_hash(name, strlen(name));<br>
+       for (i = 0; i < MAX_DATA_OBJS; i++) {<br>
+               uint32_t idx = (hval + i) % MAX_DATA_OBJS;<br>
+               uint64_t oid = vid_to_data_oid(onode_vid, idx);<br>
+<br>
+               ret = sd_read_object(oid, (char *)onode, sizeof(*onode), 0);<br>
+               if (ret != SD_RES_SUCCESS)<br>
+                       goto out;<br>
+               if (strcmp(onode-><a href="http://hdr.name" target="_blank">hdr.name</a>, name) == 0)<br>
+                       break;<br>
+       }<br>
+<br>
+       if (i == MAX_DATA_OBJS)<br>
+               ret = SD_RES_NO_OBJ;<br>
+out:<br>
+       sys->cdrv->unlock(onode_vid);<br>
+       return ret;<br>
+<br>
+}<br>
+<br>
+static int onode_read_data(struct kv_onode *onode, struct http_request *req)<br>
+{<br>
+       int ret;<br>
+<br>
+       if (!onode->hdr.inlined)<br>
+               return onode_read_extents(onode, req);<br>
+<br>
+       ret = http_request_write(req, onode->data, onode->hdr.size);<br>
+       if (ret != onode->hdr.size)<br>
+               return SD_RES_SYSTEM_ERROR;<br>
+<br>
+       return SD_RES_SUCCESS;<br>
+}<br>
+<br>
 /*<br>
  * user object name -> struct kv_onode -> sheepdog objects -> user data<br>
  *<br>
@@ -1105,121 +1181,33 @@ out:<br>
        return ret;<br>
 }<br>
<br>
-static int kv_read_extent_onode(struct http_request *req,<br>
-                               struct kv_onode *onode)<br>
-{<br>
-       struct onode_extent *ext;<br>
-       uint64_t size, total, total_size, offset, done = 0;<br>
-       uint32_t i;<br>
-       int ret;<br>
-       char *data_buf = NULL;<br>
-<br>
-       data_buf = xmalloc(READ_WRITE_BUFFER);<br>
-       total_size = onode->hdr.size;<br>
-       for (i = 0; i < onode->hdr.nr_extent; i++) {<br>
-               ext = onode->o_extent + i;<br>
-               total = min(ext->count * SD_DATA_OBJ_SIZE, total_size);<br>
-               offset = ext->start * SD_DATA_OBJ_SIZE;<br>
-               while (done < total) {<br>
-                       size = MIN(total - done, READ_WRITE_BUFFER);<br>
-                       ret = vdi_read_write(onode->hdr.data_vid, data_buf,<br>
-                                            size, offset, true);<br>
-                       if (ret != SD_RES_SUCCESS) {<br>
-                               sd_err("Failed to read for vid %"PRIx32,<br>
-                                      onode->hdr.data_vid);<br>
-                               goto out;<br>
-                       }<br>
-                       http_request_write(req, data_buf, size);<br>
-                       done += size;<br>
-                       offset += size;<br>
-                       total_size -= size;<br>
-               }<br>
-       }<br>
-out:<br>
-       free(data_buf);<br>
-       return ret;<br>
-}<br>
-<br>
-static int do_kv_read_object(struct http_request *req, const char *obj_name,<br>
-                            struct kv_onode *onode, uint32_t vid, uint32_t idx)<br>
-{<br>
-       uint64_t oid = vid_to_data_oid(vid, idx);<br>
-       int ret;<br>
-<br>
-       ret = sd_read_object(oid, (char *)onode, sizeof(*onode), 0);<br>
-       switch (ret) {<br>
-       case SD_RES_SUCCESS:<br>
-               break;<br>
-       case SD_RES_NO_OBJ:<br>
-               sd_info("object %s doesn't exist", obj_name);<br>
-               http_response_header(req, NOT_FOUND);<br>
-               goto out;<br>
-       default:<br>
-               sd_err("failed to read %s, %s", req->uri, sd_strerror(ret));<br>
-               http_response_header(req, INTERNAL_SERVER_ERROR);<br>
-               goto out;<br>
-       }<br>
-<br>
-       if (strcmp(onode-><a href="http://hdr.name" target="_blank">hdr.name</a>, obj_name) == 0) {<br>
-               http_response_header(req, OK);<br>
-               /* for inlined onode */<br>
-               if (onode->hdr.inlined)<br>
-                       http_request_write(req, onode->data, onode->hdr.size);<br>
-               else {<br>
-                       sys->cdrv->unlock(vid);<br>
-                       ret = kv_read_extent_onode(req, onode);<br>
-                       sys->cdrv->lock(vid);<br>
-                       if (ret != SD_RES_SUCCESS) {<br>
-                               sd_err("Failed to read extent onode");<br>
-                               goto out;<br>
-                       }<br>
-               }<br>
-       } else<br>
-               ret = SD_RES_OBJ_TAKEN;<br>
-out:<br>
-       return ret;<br>
-}<br>
-<br>
 int kv_read_object(struct http_request *req, const char *account,<br>
-                  const char *bucket, const char *object)<br>
+                  const char *bucket, const char *name)<br>
 {<br>
        struct kv_onode *onode = NULL;<br>
-       int ret, i;<br>
-       uint64_t hval;<br>
-       uint32_t vid;<br>
        char vdi_name[SD_MAX_VDI_LEN];<br>
+       uint32_t onode_vid;<br>
+       int ret;<br>
<br>
-       snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);<br>
-       ret = kv_lookup_vdi(vdi_name, &vid);<br>
-       if (ret < 0)<br>
-               goto out;<br>
-<br>
-       if (!kv_find_object(req, account, bucket, object))<br>
+       if (!kv_find_object(req, account, bucket, name))<br>
                return SD_RES_NO_OBJ;<br>
<br>
-       onode = xzalloc(sizeof(*onode));<br>
-<br>
-       sys->cdrv->lock(vid);<br>
-       hval = sd_hash(object, strlen(object));<br>
-       for (i = 0; i < MAX_DATA_OBJS; i++) {<br>
-               uint32_t idx = (hval + i) % MAX_DATA_OBJS;<br>
+       snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);<br>
+       ret = kv_lookup_vdi(vdi_name, &onode_vid);<br>
+       if (ret != SD_RES_SUCCESS)<br>
+               return ret;<br>
<br>
-               ret = do_kv_read_object(req, object, onode, vid, idx);<br>
-               switch (ret) {<br>
-               case SD_RES_SUCCESS:<br>
-                       goto out;<br>
-               case SD_RES_OBJ_TAKEN:<br>
-                       break;<br>
-               default:<br>
-                       ret = -1;<br>
-                       goto out;<br>
-               }<br>
-       }<br>
+       onode = xzalloc(sizeof(*onode));<br>
+       ret = onode_lookup(onode, onode_vid, name);<br>
+       if (ret != SD_RES_SUCCESS)<br>
+               goto out;<br>
<br>
-       if (i >= MAX_DATA_OBJS)<br>
-               ret = -1;<br>
+       req->data_length = onode->hdr.size;<br>
+       http_response_header(req, OK);<br>
+       ret = onode_read_data(onode, req);<br>
+       if (ret != SD_RES_SUCCESS)<br>
+               sd_err("failed to read data for %s", name);<br>
 out:<br>
-       sys->cdrv->unlock(vid);<br>
        free(onode);<br>
        return ret;<br>
 }<br>
@@ -1346,7 +1334,7 @@ int kv_list_objects(struct http_request *req, const char *account,<br>
<br>
        snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);<br>
        ret = kv_lookup_vdi(vdi_name, &vid);<br>
-       if (ret < 0)<br>
+       if (ret != SD_RES_SUCCESS)<br>
                goto out;<br>
<br>
        inode = xmalloc(sizeof(*inode));<br>
diff --git a/sheep/http/swift.c b/sheep/http/swift.c<br>
index fc25cc7..7e27acf 100644<br>
--- a/sheep/http/swift.c<br>
+++ b/sheep/http/swift.c<br>
@@ -178,9 +178,19 @@ static void swift_get_object(struct http_request *req, const char *account,<br>
                             const char *container, const char *object)<br>
 {<br>
        int ret;<br>
+<br>
        ret = kv_read_object(req, account, container, object);<br>
-       if (ret)<br>
+       switch (ret) {<br>
+       case SD_RES_SUCCESS:<br>
+               break;<br>
+       case SD_RES_NO_VDI:<br>
+       case SD_RES_NO_OBJ:<br>
                http_response_header(req, NOT_FOUND);<br>
+               break;<br>
+       default:<br>
+               http_response_header(req, INTERNAL_SERVER_ERROR);<br>
+               break;<br>
+       }<br>
 }<br>
<br>
 static void swift_put_object(struct http_request *req, const char *account,<br>
<span class="HOEnZb"><font color="#888888">--<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>