<br><br>
<div class="gmail_quote">On Thu, Mar 22, 2012 at 5:15 PM, Liu Yuan <span dir="ltr"><<a href="mailto:namei.unix@gmail.com">namei.unix@gmail.com</a>></span> wrote:<br>
<blockquote style="BORDER-LEFT:#ccc 1px solid;MARGIN:0px 0px 0px 0.8ex;PADDING-LEFT:1ex" class="gmail_quote">
<div class="HOEnZb">
<div class="h5">On 03/22/2012 04:40 PM, <a href="mailto:yaohaiting.wujue@gmail.com">yaohaiting.wujue@gmail.com</a> wrote:<br><br>> From: HaiTing Yao <<a href="mailto:wujue.yht@taobao.com">wujue.yht@taobao.com</a>><br>
><br>> Doing snapshot COW:<br>><br>> 1, If new writing request occurs and need COW for sanpshot, now read old<br>> object to buffer, then write the buffer to new object, then write the<br>> request data to new object. We can merge the latter two writing request.<br>
><br>> 2, If new writing request covers whole object, no need to read old<br>> object.<br>><br>> After the modification, pass bigger buffer to do_write_obj when doing<br>> COW, but it will not add the burden. COW is never for inode object, so<br>
> it will not use the journal.<br>><br>> Signed-off-by: HaiTing Yao <<a href="mailto:wujue.yht@taobao.com">wujue.yht@taobao.com</a>><br>> ---<br>> sheep/store.c | 29 +++++++++++++++++------------<br>
> 1 files changed, 17 insertions(+), 12 deletions(-)<br>><br>> diff --git a/sheep/store.c b/sheep/store.c<br>> index dfec235..97f1f13 100644<br>> --- a/sheep/store.c<br>> +++ b/sheep/store.c<br>> @@ -640,6 +640,7 @@ int store_create_and_write_obj(const struct sd_req *req, struct sd_rsp *rsp, voi<br>
> {<br>> struct sd_obj_req *hdr = (struct sd_obj_req *)req;<br>> struct request *request = (struct request *)data;<br>> + struct sd_obj_req cow_hdr;<br>> int ret;<br>> uint32_t epoch = hdr->epoch;<br>
> char *buf = NULL;<br>> @@ -664,19 +665,23 @@ int store_create_and_write_obj(const struct sd_req *req, struct sd_rsp *rsp, voi<br>> dprintf("%" PRIu64 ", %" PRIx64 "\n", hdr->oid, hdr->cow_oid);<br>
><br>> buf = xzalloc(SD_DATA_OBJ_SIZE);<br>> - ret = read_copy_from_cluster(request, hdr->epoch, hdr->cow_oid, buf);<br>> - if (ret != SD_RES_SUCCESS) {<br>> - eprintf("failed to read cow object\n");<br>
> - goto out;<br>> + if ((hdr->data_length != SD_DATA_OBJ_SIZE)<br>> + || (hdr->offset!= 0)) {<br><br><br></div></div>For create_and_write object, data_length of request is always<br>
SD_DATA_OBJ_SIZE and offset always 0.<br><br>Thanks,<br>Yuan<br></blockquote>
<div> </div>
<div>Yes, usually the offset is 0 and size is SD_DATA_OBJ_SIZE , but there is one exception. </div>
<div> </div>
<div>for example:</div>
<div>1) write one vdi with ID of 0x19128 from 0 to SD_DATA_OBJ_SIZE(write the first whole object)</div>
<div>2)create snapshot for this vdi, get one new vdi with ID 0x19129</div>
<div>3)write vdi again, from 1024 to 2048 this time</div>
<div>4)need read data from 0x19128-00000000, then write data to 0x19129-00000000, so occurs COW</div>
<div>5)the hdr offset is 1024, and size is 1024 now</div>
<div> </div>
<div>Thanks</div>
<div>Haiting </div>
<blockquote style="BORDER-LEFT:#ccc 1px solid;MARGIN:0px 0px 0px 0.8ex;PADDING-LEFT:1ex" class="gmail_quote">
<div class="HOEnZb">
<div class="h5"><br>> + ret = read_copy_from_cluster(request, hdr->epoch, hdr->cow_oid, buf);<br>> + if (ret != SD_RES_SUCCESS) {<br>> + eprintf("failed to read cow object\n");<br>
> + goto out;<br>> + }<br>> }<br>> - iocb.buf = buf;<br>> - iocb.length = SD_DATA_OBJ_SIZE;<br>> - iocb.offset = 0;<br>
> - ret = sd_store->write(hdr->oid, &iocb);<br>> - if (ret != SD_RES_SUCCESS)<br>> - goto out;<br>> - }<br>> - ret = do_write_obj(&iocb, hdr, epoch, request->data);<br>
> +<br>> + memcpy(buf + hdr->offset, request->data, hdr->data_length);<br>> + memcpy(&cow_hdr, hdr, sizeof(cow_hdr));<br>> + cow_hdr.offset = 0;<br>> + cow_hdr.data_length = SD_DATA_OBJ_SIZE;<br>
> +<br>> + ret = do_write_obj(&iocb, &cow_hdr, epoch, buf);<br>> + } else<br>> + ret = do_write_obj(&iocb, hdr, epoch, request->data);<br>> out:<br>> free(buf);<br>
> sd_store->close(hdr->oid, &iocb);<br><br><br></div></div></blockquote></div><br>