[sheepdog] [PATCH UPDATE] ops: refactor read_copy_from_replica()

Liu Yuan namei.unix at gmail.com
Tue Sep 11 08:54:02 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>

This function does competely the same as gateway_read_obj(), so we'd better
directly call gateway_read_obj() by faking a request.

We didn't call it in the old code because a nasty nested requests problem over
the same FD. Now with short thread and sockfd, we don't have this kind of
problem.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 - zero out struct request read_req;

 sheep/ops.c |   94 ++++++++++-------------------------------------------------
 1 file changed, 15 insertions(+), 79 deletions(-)

diff --git a/sheep/ops.c b/sheep/ops.c
index 4c3e9ac..77ca956 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -744,90 +744,26 @@ 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 vnode_info *vnodes, uint32_t epoch,
+static int read_copy_from_replica(struct request *req, uint32_t epoch,
 				  uint64_t oid, char *buf)
 {
-	int i, j, nr_copies, ret;
-	struct sd_req hdr;
-	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
-	struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
-	struct sd_vnode *v;
-	char name[128];
-	int rounded_rand, local = -1;
-
-	nr_copies = get_obj_copy_number(oid, vnodes->nr_zones);
-	oid_to_vnodes(vnodes->vnodes, vnodes->nr_vnodes, oid,
-		      nr_copies, obj_vnodes);
-
-	/* first try to read from local copy */
-	for (i = 0; i < nr_copies; i++) {
-		struct siocb iocb;
-
-		v = obj_vnodes[i];
-		addr_to_str(name, sizeof(name), v->nid.addr, 0);
-
-		if (vnode_is_local(v)) {
-			memset(&iocb, 0, sizeof(iocb));
-			iocb.epoch = epoch;
-			iocb.buf = buf;
-			iocb.length = SD_DATA_OBJ_SIZE;
-			iocb.offset = 0;
-			ret = sd_store->read(oid, &iocb);
-			if (ret != SD_RES_SUCCESS) {
-				local = i;
-				break;
-			}
-			goto out;
-		}
-	}
-
-	/* then read random copy from cluster for better load balance */
-	rounded_rand = random() % nr_copies;
+	struct request read_req = { };
+	struct sd_req *hdr = &read_req.rq;
 
-	for (i = 0; i < nr_copies; i++) {
-		unsigned wlen, rlen;
-		int fd;
-
-		j = (i + rounded_rand) % nr_copies;
-
-		/* bypass the local copy */
-		if (local == j)
-			continue;
-
-		v = obj_vnodes[j];
-		addr_to_str(name, sizeof(name), v->nid.addr, 0);
-
-		fd = connect_to(name, v->nid.port);
-		if (fd < 0)
-			continue;
+	/* Create a fake gateway read request */
+	sd_init_req(hdr, SD_OP_READ_OBJ);
+	hdr->data_length = SD_DATA_OBJ_SIZE;
+	hdr->epoch = epoch;
 
-		rlen = SD_DATA_OBJ_SIZE;
-		wlen = 0;
+	hdr->obj.oid = oid;
+	hdr->obj.offset = 0;
+	hdr->obj.copies = get_req_copy_number(req);
 
-		sd_init_req(&hdr, SD_OP_READ_PEER);
-		hdr.epoch = epoch;
-		hdr.data_length = rlen;
+	read_req.data = buf;
+	read_req.op = get_sd_op(hdr->opcode);
+	read_req.vinfo = req->vinfo;
 
-		hdr.obj.oid = oid;
-		hdr.obj.offset = 0;
-
-		ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
-
-		close(fd);
-
-		if (ret) {
-			dprintf("%x, %x\n", ret, rsp->result);
-			continue;
-		}
-
-		if (rsp->result == SD_RES_SUCCESS)
-			break;
-	}
-
-	ret = rsp->result;
-	dprintf("%"PRIx64" ret:%x\n", oid, ret);
-out:
-	return ret;
+	return gateway_read_obj(&read_req);
 }
 
 int peer_remove_obj(struct request *req)
@@ -938,7 +874,7 @@ int peer_create_and_write_obj(struct request *req)
 			goto out;
 		}
 		if (hdr->data_length != SD_DATA_OBJ_SIZE) {
-			ret = read_copy_from_replica(req->vinfo, hdr->epoch,
+			ret = read_copy_from_replica(req, hdr->epoch,
 						     hdr->obj.cow_oid, buf);
 			if (ret != SD_RES_SUCCESS) {
 				eprintf("failed to read cow object\n");
-- 
1.7.10.2




More information about the sheepdog mailing list