<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/16 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 add Robin and myself to the contributor list of this file<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 | 102 ++++++++++++++++++++++++++++++++++++++++---------------<br>
1 file changed, 75 insertions(+), 27 deletions(-)<br>
<br>
diff --git a/sheep/http/kv.c b/sheep/http/kv.c<br>
index c578716..8dc4db8 100644<br>
--- a/sheep/http/kv.c<br>
+++ b/sheep/http/kv.c<br>
@@ -1,5 +1,7 @@<br>
/*<br>
* Copyright (C) 2013 MORITA Kazutaka <<a href="mailto:morita.kazutaka@gmail.com">morita.kazutaka@gmail.com</a>><br>
+ * Copyright (C) 2013 Robin Dong <<a href="mailto:sanbai@taobao.com">sanbai@taobao.com</a>><br>
+ * Copyright (C) 2013 Liu Yuan <<a href="mailto:namei.unix@gmail.com">namei.unix@gmail.com</a>><br>
*<br>
* This program is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU General Public License version<br>
@@ -919,11 +921,57 @@ out:<br>
return ret;<br>
}<br>
<br>
+static int vdi_read_write(uint32_t vid, char *data, size_t length,<br>
+ off_t offset, bool read)<br>
+{<br>
+ struct sd_req hdr;<br>
+ uint32_t idx = offset / SD_DATA_OBJ_SIZE;<br>
+ uint64_t done = 0;<br>
+ struct request_iocb *iocb;<br>
+ int ret;<br>
+<br>
+ iocb = local_req_init();<br>
+ if (!iocb)<br>
+ return SD_RES_SYSTEM_ERROR;<br>
+<br>
+ offset %= SD_DATA_OBJ_SIZE;<br>
+ while (done < length) {<br>
+ size_t len = min(length - done, SD_DATA_OBJ_SIZE - offset);<br>
+<br>
+ if (read) {<br>
+ sd_init_req(&hdr, SD_OP_READ_OBJ);<br>
+ } else {<br>
+ sd_init_req(&hdr, SD_OP_CREATE_AND_WRITE_OBJ);<br>
+ hdr.flags = SD_FLAG_CMD_WRITE;<br>
+ }<br>
+ hdr.data_length = len;<br>
+ hdr.obj.oid = vid_to_data_oid(vid, idx);<br>
+ hdr.obj.offset = offset;<br>
+<br>
+ ret = exec_local_req_async(&hdr, data, iocb);<br>
+ if (ret != SD_RES_SUCCESS)<br>
+ sd_err("failed to write object %" PRIx64 ", %s",<br>
+ hdr.obj.oid, sd_strerror(ret));<br>
+<br>
+ offset += len;<br>
+ if (offset == SD_DATA_OBJ_SIZE) {<br>
+ offset = 0;<br>
+ idx++;<br>
+ }<br>
+ done += len;<br>
+ data += len;<br>
+ }<br>
+<br>
+ return local_req_wait(iocb);<br>
+}<br>
+<br>
+#define READ_WRITE_BUFFER (SD_DATA_OBJ_SIZE * 25) /* no rationale */<br>
+<br>
static int kv_create_extent_onode(struct http_request *req, uint32_t data_vid,<br>
struct kv_onode *onode, ssize_t *total_size)<br>
{<br>
ssize_t size;<br>
- uint64_t start = 0, count, limit, block;<br>
+ uint64_t start = 0, count, done = 0, total, offset;<br>
int ret;<br>
char *data_buf = NULL;<br>
<br>
@@ -931,6 +979,7 @@ static int kv_create_extent_onode(struct http_request *req, uint32_t data_vid,<br>
sys->cdrv->lock(data_vid);<br>
ret = oalloc_new_prepare(data_vid, &start, count);<br>
sys->cdrv->unlock(data_vid);<br>
+ sd_debug("start: %lu, count: %lu", start, count);<br>
if (ret != SD_RES_SUCCESS) {<br>
sd_err("Failed to prepare allocation of %lu bytes!",<br>
req->data_length);<br>
@@ -939,24 +988,23 @@ static int kv_create_extent_onode(struct http_request *req, uint32_t data_vid,<br>
}<br>
<br>
/* receive and write data at first, then write onode */<br>
- data_buf = xmalloc(SD_DATA_OBJ_SIZE);<br>
-<br>
- sd_debug("start: %lu, count: %lu", start, count);<br>
- for (block = start, limit = start + count; block < limit; block++) {<br>
- sd_debug("block: %lu, limit: %lu", block, limit);<br>
- size = http_request_read(req, data_buf, SD_DATA_OBJ_SIZE);<br>
- *total_size += size;<br>
- ret = sd_write_object(vid_to_data_oid(data_vid, block),<br>
- data_buf, size, 0, true);<br>
+ data_buf = xmalloc(READ_WRITE_BUFFER);<br>
+ offset = start * SD_DATA_OBJ_SIZE;<br>
+ total = req->data_length;<br>
+ while (done < total) {<br>
+ size = http_request_read(req, data_buf, READ_WRITE_BUFFER);<br>
+ ret = vdi_read_write(data_vid, data_buf, size, offset, false);<br>
if (ret != SD_RES_SUCCESS) {<br>
sd_err("Failed to write data object for %" PRIx32" %s",<br>
data_vid, sd_strerror(ret));<br>
goto out;<br>
}<br>
- if (size < SD_DATA_OBJ_SIZE)<br>
- break;<br>
+ done += size;<br>
+ offset += size;<br>
}<br>
<br>
+ *total_size = done;<br>
+<br>
sd_debug("DATA_LENGTH: %lu, total size: %lu, last blocks: %lu",<br>
req->data_length, *total_size, start);<br>
<br>
@@ -975,6 +1023,7 @@ static int kv_create_extent_onode(struct http_request *req, uint32_t data_vid,<br>
onode->o_extent[0].count = count;<br>
onode->hdr.nr_extent = 1;<br>
out:<br>
+ free(data_buf);<br>
return ret;<br>
}<br>
<br>
@@ -1075,32 +1124,31 @@ static int kv_read_extent_onode(struct http_request *req,<br>
struct kv_onode *onode)<br>
{<br>
struct onode_extent *ext;<br>
- uint64_t oid, block, size, total_size, limit;<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(SD_DATA_OBJ_SIZE);<br>
-<br>
+ data_buf = xmalloc(READ_WRITE_BUFFER);<br>
total_size = onode->hdr.size;<br>
- ext = onode->o_extent;<br>
for (i = 0; i < onode->hdr.nr_extent; i++) {<br>
- limit = ext->count + ext->start;<br>
- for (block = ext->start; block < limit; block++) {<br>
- oid = vid_to_data_oid(onode->hdr.data_vid, block);<br>
- if (total_size < SD_DATA_OBJ_SIZE)<br>
- size = total_size;<br>
- else<br>
- size = SD_DATA_OBJ_SIZE;<br>
- ret = sd_read_object(oid, data_buf, size, 0);<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>
+ sd_err("%ld", size);<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 oid %lx", oid);<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>
- sd_debug("read extented block %lu, size %lu",<br>
- block, size);<br>
}<br>
}<br>
out:<br>
<span class="HOEnZb"><font color="#888888">--<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>