[Sheepdog] [PATCH v2] sheep: reduce snapshot COW read/write

yaohaiting.wujue at gmail.com yaohaiting.wujue at gmail.com
Fri Mar 23 09:15:31 CET 2012


From: HaiTing Yao <wujue.yht at taobao.com>

Doing snapshot COW:

1, If new writing request occurs and need COW for sanpshot, now read old
object to buffer, then write the buffer to new object, then write the
request data to new object. We can merge the latter two writing request.

2, If new writing request covers whole object, no need to read old
object.

After the modification, pass bigger buffer to do_write_obj when doing
COW, but it will not add the burden. COW is never for inode object, so
it will not use the journal.

Signed-off-by: HaiTing Yao <wujue.yht at taobao.com>
---
 sheep/store.c |   35 ++++++++++++++++++++++-------------
 1 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/sheep/store.c b/sheep/store.c
index dfec235..82bbff1 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -640,6 +640,7 @@ int store_create_and_write_obj(const struct sd_req *req, struct sd_rsp *rsp, voi
 {
 	struct sd_obj_req *hdr = (struct sd_obj_req *)req;
 	struct request *request = (struct request *)data;
+	struct sd_obj_req cow_hdr;
 	int ret;
 	uint32_t epoch = hdr->epoch;
 	char *buf = NULL;
@@ -663,22 +664,30 @@ int store_create_and_write_obj(const struct sd_req *req, struct sd_rsp *rsp, voi
 	if (hdr->flags & SD_FLAG_CMD_COW) {
 		dprintf("%" PRIu64 ", %" PRIx64 "\n", hdr->oid, hdr->cow_oid);
 
-		buf = xzalloc(SD_DATA_OBJ_SIZE);
-		ret = read_copy_from_cluster(request, hdr->epoch, hdr->cow_oid, buf);
-		if (ret != SD_RES_SUCCESS) {
-			eprintf("failed to read cow object\n");
+		buf = zalloc(SD_DATA_OBJ_SIZE);
+		if (!buf) {
+			eprintf("can not allocate memory\n");
 			goto out;
 		}
-		iocb.buf = buf;
-		iocb.length = SD_DATA_OBJ_SIZE;
-		iocb.offset = 0;
-		ret = sd_store->write(hdr->oid, &iocb);
-		if (ret != SD_RES_SUCCESS)
-			goto out;
-	}
-	ret = do_write_obj(&iocb, hdr, epoch, request->data);
+		if (hdr->data_length != SD_DATA_OBJ_SIZE) {
+			ret = read_copy_from_cluster(request, hdr->epoch, hdr->cow_oid, buf);
+			if (ret != SD_RES_SUCCESS) {
+				eprintf("failed to read cow object\n");
+				goto out;
+			}
+		}
+
+		memcpy(buf + hdr->offset, request->data, hdr->data_length);
+		memcpy(&cow_hdr, hdr, sizeof(cow_hdr));
+		cow_hdr.offset = 0;
+		cow_hdr.data_length = SD_DATA_OBJ_SIZE;
+
+		ret = do_write_obj(&iocb, &cow_hdr, epoch, buf);
+	} else
+		ret = do_write_obj(&iocb, hdr, epoch, request->data);
 out:
-	free(buf);
+	if (buf)
+		free(buf);
 	sd_store->close(hdr->oid, &iocb);
 	return ret;
 }
-- 
1.7.1




More information about the sheepdog mailing list