[sheepdog] [PATCH 03/10] sheep: rework cow object handling

Liu Yuan namei.unix at gmail.com
Tue Oct 15 16:36:36 CEST 2013


cow handling should be handled in the gateway instead of backend store because
copy-on-write's copy(read) and write should be object type agnostic. With this
patch, we can add cow capability to erasured vdi.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 sheep/gateway.c |   34 +++++++++++++++++++++++++++
 sheep/ops.c     |   70 ++++---------------------------------------------------
 2 files changed, 39 insertions(+), 65 deletions(-)

diff --git a/sheep/gateway.c b/sheep/gateway.c
index a2dc7e4..ebe925b 100644
--- a/sheep/gateway.c
+++ b/sheep/gateway.c
@@ -548,6 +548,37 @@ int gateway_write_obj(struct request *req)
 	return gateway_forward_request(req);
 }
 
+static int gateway_handle_cow(struct request *req)
+{
+	uint64_t oid = req->rq.obj.oid;
+	size_t len = get_objsize(oid);
+	struct sd_req hdr, *req_hdr = &req->rq;
+	char *buf = xmalloc(len);
+	int ret;
+
+	if (req->rq.data_length != len) {
+		/* Partial write, need read the copy first */
+		sd_init_req(&hdr, SD_OP_READ_OBJ);
+		hdr.obj.oid = req_hdr->obj.cow_oid;
+		hdr.data_length = len;
+		hdr.obj.offset = 0;
+		ret = exec_local_req(&hdr, buf);
+		if (ret != SD_RES_SUCCESS)
+			goto out;
+	}
+
+	memcpy(buf + req_hdr->obj.offset, req->data, req_hdr->data_length);
+	sd_init_req(&hdr, SD_OP_CREATE_AND_WRITE_OBJ);
+	hdr.flags = SD_FLAG_CMD_WRITE;
+	hdr.obj.oid = oid;
+	hdr.data_length = len;
+	hdr.obj.offset = 0;
+	ret = exec_local_req(&hdr, buf);
+out:
+	free(buf);
+	return ret;
+}
+
 int gateway_create_and_write_obj(struct request *req)
 {
 	uint64_t oid = req->rq.obj.oid;
@@ -555,6 +586,9 @@ int gateway_create_and_write_obj(struct request *req)
 	if (oid_is_readonly(oid))
 		return SD_RES_READONLY;
 
+	if (req->rq.flags & SD_FLAG_CMD_COW)
+		return gateway_handle_cow(req);
+
 	if (!bypass_object_cache(req))
 		return object_cache_handle_request(req);
 
diff --git a/sheep/ops.c b/sheep/ops.c
index 340c8d4..7885378 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -874,28 +874,6 @@ static int local_kill_node(const struct sd_req *req, struct sd_rsp *rsp,
 	return SD_RES_SUCCESS;
 }
 
-static int read_copy_from_replica(struct request *req, uint32_t epoch,
-				  uint64_t oid, char *buf)
-{
-	struct request read_req = { };
-	struct sd_req *hdr = &read_req.rq;
-
-	/* Create a fake gateway read request */
-	sd_init_req(hdr, SD_OP_READ_OBJ);
-	hdr->data_length = SD_DATA_OBJ_SIZE;
-	hdr->epoch = epoch;
-
-	hdr->obj.oid = oid;
-	hdr->obj.offset = 0;
-	hdr->obj.copies = get_req_copy_number(req);
-
-	read_req.data = buf;
-	read_req.op = get_sd_op(hdr->opcode);
-	read_req.vinfo = req->vinfo;
-
-	return gateway_read_obj(&read_req);
-}
-
 static int peer_remove_obj(struct request *req)
 {
 	uint64_t oid = req->rq.obj.oid;
@@ -936,16 +914,6 @@ out:
 	return ret;
 }
 
-static int do_create_and_write_obj(struct siocb *iocb, struct sd_req *hdr,
-				   uint32_t epoch, void *data)
-{
-	iocb->buf = data;
-	iocb->length = hdr->data_length;
-	iocb->offset = hdr->obj.offset;
-
-	return sd_store->create_and_write(hdr->obj.oid, iocb);
-}
-
 static int peer_write_obj(struct request *req)
 {
 	struct sd_req *hdr = &req->rq;
@@ -963,41 +931,13 @@ static int peer_write_obj(struct request *req)
 static int peer_create_and_write_obj(struct request *req)
 {
 	struct sd_req *hdr = &req->rq;
-	struct sd_req cow_hdr;
-	uint32_t epoch = hdr->epoch;
-	uint64_t oid = hdr->obj.oid;
-	char *buf = NULL;
-	struct siocb iocb;
-	int ret = SD_RES_SUCCESS;
+	struct siocb iocb = { };
 
-	memset(&iocb, 0, sizeof(iocb));
-	iocb.epoch = epoch;
-	iocb.length = get_store_objsize(oid);
+	iocb.epoch = hdr->epoch;
+	iocb.buf = req->data;
+	iocb.length = hdr->data_length;
 	iocb.ec_index = hdr->obj.ec_index;
-	if (hdr->flags & SD_FLAG_CMD_COW) {
-		sd_debug("%" PRIx64 ", %" PRIx64, oid, hdr->obj.cow_oid);
-
-		buf = xvalloc(SD_DATA_OBJ_SIZE);
-		if (hdr->data_length != SD_DATA_OBJ_SIZE) {
-			ret = read_copy_from_replica(req, hdr->epoch,
-						     hdr->obj.cow_oid, buf);
-			if (ret != SD_RES_SUCCESS) {
-				sd_err("failed to read cow object");
-				goto out;
-			}
-		}
-
-		memcpy(buf + hdr->obj.offset, req->data, hdr->data_length);
-		memcpy(&cow_hdr, hdr, sizeof(cow_hdr));
-		cow_hdr.data_length = SD_DATA_OBJ_SIZE;
-		cow_hdr.obj.offset = 0;
-		ret = do_create_and_write_obj(&iocb, &cow_hdr, epoch, buf);
-	} else
-		ret = do_create_and_write_obj(&iocb, hdr, epoch, req->data);
-out:
-	if (buf)
-		free(buf);
-	return ret;
+	return sd_store->create_and_write(hdr->obj.oid, &iocb);
 }
 
 static struct sd_op_template sd_ops[] = {
-- 
1.7.9.5




More information about the sheepdog mailing list