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