[sheepdog] [PATCH] erasure: allow x nodes to serve write request with x:y policy

Liu Yuan namei.unix at gmail.com
Sat Dec 7 14:30:23 CET 2013


There is no technical reason that prvent us from serving the both read and write
requests if there are x nodes alove in the cluster with x:y policy.

E.g, with 4 nodes alive with 4:2 formated, the cluster will be still operational
instead of denial of service with this patch.

This patch also fixes a memory leak in erorr case.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 sheep/gateway.c |   27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/sheep/gateway.c b/sheep/gateway.c
index f0cb514..0806edd 100644
--- a/sheep/gateway.c
+++ b/sheep/gateway.c
@@ -498,7 +498,7 @@ static int gateway_forward_request(struct request *req)
 	struct forward_info fi;
 	struct sd_req hdr;
 	const struct sd_node *target_nodes[SD_MAX_NODES];
-	int nr_copies = get_req_copy_number(req), nr_to_send = 0;
+	int nr_copies = get_req_copy_number(req), nr_reqs, nr_to_send = 0;
 	struct req_iter *reqs = NULL;
 
 	sd_debug("%"PRIx64, oid);
@@ -510,11 +510,24 @@ static int gateway_forward_request(struct request *req)
 	if (!reqs)
 		return SD_RES_NETWORK_ERROR;
 
-	/* avoid out range of target_nodes[] */
+	/*
+	 * For replication, we send number of available zones copies.
+	 *
+	 * For erasure, we need at least number of data strips to send to avoid
+	 * overflow of target_nodes.
+	 */
+	nr_reqs = nr_to_send;
 	if (nr_to_send > nr_copies) {
-		sd_err("There isn't enough copies(%d) to send out (%d)",
-		       nr_copies, nr_to_send);
-		return SD_RES_SYSTEM_ERROR;
+		int ds;
+		/* Only for erasure code, nr_to_send might > nr_copies */
+		ec_policy_to_dp(req->rq.obj.copy_policy, &ds, NULL);
+		if (nr_copies < ds) {
+			sd_err("There isn't enough copies(%d) to send out (%d)",
+			       nr_copies, nr_to_send);
+			err_ret = SD_RES_SYSTEM_ERROR;
+			goto out;
+		}
+		nr_to_send = ds;
 	}
 
 	for (i = 0; i < nr_to_send; i++) {
@@ -551,8 +564,8 @@ static int gateway_forward_request(struct request *req)
 		if (ret != SD_RES_SUCCESS)
 			err_ret = ret;
 	}
-
-	finish_requests(req, reqs, nr_to_send);
+out:
+	finish_requests(req, reqs, nr_reqs);
 	return err_ret;
 }
 
-- 
1.7.9.5




More information about the sheepdog mailing list