<div dir="ltr">Reviewed-by: Robin Dong <<a href="mailto:sanbai@taobao.com">sanbai@taobao.com</a>></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/12/7 Liu Yuan <span dir="ltr"><<a href="mailto:namei.unix@gmail.com" target="_blank">namei.unix@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">There is no technical reason that prvent us from serving the both read and write<br>
requests if there are x nodes alove in the cluster with x:y policy.<br>
<br>
E.g, with 4 nodes alive with 4:2 formated, the cluster will be still operational<br>
instead of denial of service with this patch.<br>
<br>
This patch also fixes a memory leak in erorr case.<br>
<br>
Signed-off-by: Liu Yuan <<a href="mailto:namei.unix@gmail.com">namei.unix@gmail.com</a>><br>
---<br>
 sheep/gateway.c |   27 ++++++++++++++++++++-------<br>
 1 file changed, 20 insertions(+), 7 deletions(-)<br>
<br>
diff --git a/sheep/gateway.c b/sheep/gateway.c<br>
index f0cb514..0806edd 100644<br>
--- a/sheep/gateway.c<br>
+++ b/sheep/gateway.c<br>
@@ -498,7 +498,7 @@ static int gateway_forward_request(struct request *req)<br>
        struct forward_info fi;<br>
        struct sd_req hdr;<br>
        const struct sd_node *target_nodes[SD_MAX_NODES];<br>
-       int nr_copies = get_req_copy_number(req), nr_to_send = 0;<br>
+       int nr_copies = get_req_copy_number(req), nr_reqs, nr_to_send = 0;<br>
        struct req_iter *reqs = NULL;<br>
<br>
        sd_debug("%"PRIx64, oid);<br>
@@ -510,11 +510,24 @@ static int gateway_forward_request(struct request *req)<br>
        if (!reqs)<br>
                return SD_RES_NETWORK_ERROR;<br>
<br>
-       /* avoid out range of target_nodes[] */<br>
+       /*<br>
+        * For replication, we send number of available zones copies.<br>
+        *<br>
+        * For erasure, we need at least number of data strips to send to avoid<br>
+        * overflow of target_nodes.<br>
+        */<br>
+       nr_reqs = nr_to_send;<br>
        if (nr_to_send > nr_copies) {<br>
-               sd_err("There isn't enough copies(%d) to send out (%d)",<br>
-                      nr_copies, nr_to_send);<br>
-               return SD_RES_SYSTEM_ERROR;<br>
+               int ds;<br>
+               /* Only for erasure code, nr_to_send might > nr_copies */<br>
+               ec_policy_to_dp(req->rq.obj.copy_policy, &ds, NULL);<br>
+               if (nr_copies < ds) {<br>
+                       sd_err("There isn't enough copies(%d) to send out (%d)",<br>
+                              nr_copies, nr_to_send);<br>
+                       err_ret = SD_RES_SYSTEM_ERROR;<br>
+                       goto out;<br>
+               }<br>
+               nr_to_send = ds;<br>
        }<br>
<br>
        for (i = 0; i < nr_to_send; i++) {<br>
@@ -551,8 +564,8 @@ static int gateway_forward_request(struct request *req)<br>
                if (ret != SD_RES_SUCCESS)<br>
                        err_ret = ret;<br>
        }<br>
-<br>
-       finish_requests(req, reqs, nr_to_send);<br>
+out:<br>
+       finish_requests(req, reqs, nr_reqs);<br>
        return err_ret;<br>
 }<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.7.9.5<br>
<br>
--<br>
sheepdog mailing list<br>
<a href="mailto:sheepdog@lists.wpkg.org">sheepdog@lists.wpkg.org</a><br>
<a href="http://lists.wpkg.org/mailman/listinfo/sheepdog" target="_blank">http://lists.wpkg.org/mailman/listinfo/sheepdog</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br>--<br>Best Regard<br>Robin Dong
</div>