[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