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 <[email protected]>
---
 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 7885378..cacca06 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -937,6 +937,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 4367a9e..c6ef128 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 1568091..b3396a6 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

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to