<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>