[sheepdog] [PATCH v2 18/21] sheep: fix default_create_and_write()

Liu Yuan namei.unix at gmail.com
Wed Oct 16 07:50:44 CEST 2013


Cluster snapshot's create request will have copy_policy set in the sd_req but
without vdi registered. So we have to pass copy_policy down and check it in the
default_create_and_write.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 sheep/gateway.c     |   20 ++++++++++++++------
 sheep/ops.c         |    1 +
 sheep/plain_store.c |    6 +++---
 sheep/sheep_priv.h  |    2 ++
 4 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/sheep/gateway.c b/sheep/gateway.c
index ebe925b..e9d08c3 100644
--- a/sheep/gateway.c
+++ b/sheep/gateway.c
@@ -170,15 +170,22 @@ out:
 	return reqs;
 }
 
-/* Requests from dog might not have vdi registered yet in the vdi state */
-static bool is_erasure_req(struct request *req)
+/*
+ * We have two kinds of requests that might go for erasured object:
+ *  1. requests without setting copy_policy but expect vdi's copy policy is
+ *     registered in vdi states, e.g, normal requests from QEMU
+ *  2. requests with copy_policy explicitly set because vdi's copy policy is
+ *     not registered, e.g, requests from 'cluster snapshot load'.
+ *
+ * So we have to firstly check copy_policy directly from iocb and then call
+ * get_vdi_copy_policy(oid).
+ */
+bool is_erasure_obj(uint64_t oid, uint8_t copy_policy)
 {
-	uint64_t oid = req->rq.obj.oid;
-
 	if (is_vdi_obj(oid))
 		return false;
 
-	if (req->rq.obj.copy_policy > 0)
+	if (copy_policy > 0)
 		return true;
 
 	return get_vdi_copy_policy(oid_to_vid(oid)) > 0;
@@ -192,7 +199,7 @@ bool is_erasure_oid(uint64_t oid)
 /* Prepare request iterator and buffer for each replica */
 static struct req_iter *prepare_requests(struct request *req, int *nr)
 {
-	if (is_erasure_req(req))
+	if (is_erasure_obj(req->rq.obj.oid, req->rq.obj.copy_policy))
 		return prepare_erasure_requests(req, nr);
 	else
 		return prepare_replication_requests(req, nr);
@@ -499,6 +506,7 @@ static int gateway_forward_request(struct request *req)
 		wlen = reqs[i].wlen;
 		hdr.obj.offset = reqs[i].off;
 		hdr.obj.ec_index = i;
+		hdr.obj.copy_policy = req->rq.obj.copy_policy;
 		ret = send_req(sfd->fd, &hdr, reqs[i].buf, wlen,
 			       sheep_need_retry, req->rq.epoch,
 			       MAX_RETRY_COUNT);
diff --git a/sheep/ops.c b/sheep/ops.c
index 5db2ef3..e39a21b 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -941,6 +941,7 @@ static int peer_create_and_write_obj(struct request *req)
 	iocb.buf = req->data;
 	iocb.length = hdr->data_length;
 	iocb.ec_index = hdr->obj.ec_index;
+	iocb.copy_policy = hdr->obj.copy_policy;
 	return sd_store->create_and_write(hdr->obj.oid, &iocb);
 }
 
diff --git a/sheep/plain_store.c b/sheep/plain_store.c
index 1bfc58e..7d8b5d0 100644
--- a/sheep/plain_store.c
+++ b/sheep/plain_store.c
@@ -341,6 +341,7 @@ int default_create_and_write(uint64_t oid, const struct siocb *iocb)
 	int flags = prepare_iocb(oid, iocb, true);
 	int ret, fd;
 	uint32_t len = iocb->length;
+	bool ec = is_erasure_obj(oid, iocb->copy_policy);
 
 	sd_debug("%"PRIx64, oid);
 	get_obj_path(oid, path, sizeof(path));
@@ -374,7 +375,7 @@ int default_create_and_write(uint64_t oid, const struct siocb *iocb)
 		return err_to_sderr(path, oid, errno);
 	}
 
-	ret = prealloc(fd, get_store_objsize(oid));
+	ret = prealloc(fd, ec ? SD_EC_OBJECT_SIZE : get_objsize(oid));
 	if (ret < 0) {
 		ret = err_to_sderr(path, oid, errno);
 		goto out;
@@ -393,8 +394,7 @@ int default_create_and_write(uint64_t oid, const struct siocb *iocb)
 		ret = err_to_sderr(path, oid, errno);
 		goto out;
 	}
-	if (is_erasure_oid(oid) &&
-	    set_erasure_index(path, iocb->ec_index) < 0) {
+	if (ec && set_erasure_index(path, iocb->ec_index) < 0) {
 		ret = err_to_sderr(path, oid, errno);
 		goto out;
 	}
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index bcb260e..615d912 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -164,6 +164,7 @@ struct siocb {
 	uint32_t length;
 	uint32_t offset;
 	uint8_t ec_index;
+	uint8_t copy_policy;
 };
 
 /* This structure is used to pass parameters to vdi_* functions. */
@@ -409,6 +410,7 @@ int gateway_write_obj(struct request *req);
 int gateway_create_and_write_obj(struct request *req);
 int gateway_remove_obj(struct request *req);
 bool is_erasure_oid(uint64_t oid);
+bool is_erasure_obj(uint64_t oid, uint8_t copy_policy);
 
 /* object_cache */
 
-- 
1.7.9.5




More information about the sheepdog mailing list