[sheepdog] [PATCH v2 4/7] recovery: make IO request to wait when the requested object is in recovery

levin li levin108 at gmail.com
Wed May 23 09:02:26 CEST 2012


From: levin li <xingke.lwp at taobao.com>

When an object requested is in recovery, we should put it into
the wait_obj_queue to make the request wait until the object is
recovered by the recovery work.

Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 sheep/group.c      |    1 +
 sheep/recovery.c   |    6 +++++-
 sheep/sdnet.c      |   25 ++++++++++++++++++++-----
 sheep/sheep_priv.h |    2 ++
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/sheep/group.c b/sheep/group.c
index 9052cf9..dec5af0 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -1379,6 +1379,7 @@ int create_cluster(int port, int64_t zone, int nr_vnodes)
 	INIT_LIST_HEAD(&sys->request_queue);
 	INIT_LIST_HEAD(&sys->event_queue);
 	INIT_LIST_HEAD(&sys->wait_rw_queue);
+	INIT_LIST_HEAD(&sys->wait_obj_queue);
 
 	ret = send_join_request(&sys->this_node);
 	if (ret != 0)
diff --git a/sheep/recovery.c b/sheep/recovery.c
index 0c63483..a2177cf 100644
--- a/sheep/recovery.c
+++ b/sheep/recovery.c
@@ -549,10 +549,11 @@ static void resume_wait_recovery_requests(void)
 static void do_recover_main(struct work *work)
 {
 	struct recovery_work *rw = container_of(work, struct recovery_work, work);
-	uint64_t oid;
+	uint64_t oid, recovered_oid = rw->oids[rw->done];
 
 	if (rw->state == RW_INIT) {
 		rw->state = RW_RUN;
+		recovered_oid = 0;
 		resume_wait_recovery_requests();
 	} else if (!rw->retry) {
 		rw->done++;
@@ -562,6 +563,9 @@ static void do_recover_main(struct work *work)
 
 	oid = rw->oids[rw->done];
 
+	if (recovered_oid)
+		resume_retry_requests(recovered_oid);
+
 	if (rw->retry && !next_rw) {
 		rw->retry = 0;
 
diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index 4e2acaa..89b4c6c 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -231,11 +231,9 @@ static int check_request(struct request *req)
 				req->rp.result = SD_RES_OBJ_RECOVERING;
 				list_add_tail(&req->request_list,
 						&sys->wait_rw_queue);
-			} else {
-				req->rp.result = SD_RES_NEW_NODE_VER;
-				sys->nr_outstanding_io++;
-				req->work.done(&req->work);
-			}
+			} else
+				list_add_tail(&req->request_list,
+						&sys->wait_obj_queue);
 		} else {
 			/* Gateway request */
 			list_add_tail(&req->request_list, &sys->req_wait_for_obj_list);
@@ -296,6 +294,23 @@ void resume_wait_epoch_requests(void)
 	}
 }
 
+void resume_retry_requests(uint64_t oid)
+{
+	struct request *req, *t;
+
+	list_for_each_entry_safe(req, t, &sys->wait_obj_queue,
+			request_list) {
+		/* the object requested by a pending request has been
+		 * recovered, notify the pending request. */
+		if (req->local_oid == oid) {
+			dprintf("retry %" PRIx64 "\n", req->local_oid);
+			list_del(&req->request_list);
+			list_add_tail(&req->request_list, &sys->request_queue);
+			process_request_event_queues();
+		}
+	}
+}
+
 static void queue_request(struct request *req)
 {
 	struct sd_req *hdr = &req->rq;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 410e144..24f4544 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -137,6 +137,7 @@ struct cluster_info {
 	struct list_head request_queue;
 	struct list_head event_queue;
 	struct list_head wait_rw_queue;
+	struct list_head wait_obj_queue;
 	struct event_struct *cur_cevent;
 	int nr_outstanding_io;
 	int nr_outstanding_reqs;
@@ -265,6 +266,7 @@ int is_access_to_busy_objects(uint64_t oid);
 
 void resume_pending_requests(void);
 void resume_wait_epoch_requests(void);
+void resume_retry_requests(uint64_t oid);
 
 int create_cluster(int port, int64_t zone, int nr_vnodes);
 int leave_cluster(void);
-- 
1.7.10




More information about the sheepdog mailing list