[sheepdog] [PATCH] When network is broken, unblock all I/O requests.

Xu Yifeng skypexu at gmail.com
Tue Mar 3 09:27:15 CET 2015


Current sbd code does not reconnect network, the change does not try
to fix this, but instead, drain all I/O requests. This makes application
killable, otherwise an application can be blocked forever.
---
 sbd/sheep.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/sbd/sheep.c b/sbd/sheep.c
index 746f0ea..b8d3a18 100644
--- a/sbd/sheep.c
+++ b/sbd/sheep.c
@@ -279,7 +279,7 @@ static int submit_sheep_request(struct sheep_request *req)
 {
 	struct sd_req hdr = {};
 	struct sbd_device *dev = sheep_request_to_device(req);
-	int ret;
+	int ret = 0;
 
 	hdr.id = req->seq_num;
 	hdr.data_length = req->length;
@@ -316,9 +316,8 @@ static int submit_sheep_request(struct sheep_request *req)
 	}
 	sbd_debug("add oid %llx off %d, len %d, seq %u, type %d\n", req->oid,
 		  req->offset, req->length, req->seq_num, req->type);
-	wake_up(&dev->reaper_wq);
-	return 0;
 err:
+	wake_up(&dev->reaper_wq);
 	return ret;
 }
 
@@ -611,6 +610,20 @@ out:
 	return req;
 }
 
+static struct sheep_request *fetch_first_inflight_request(struct sbd_device *dev)
+{
+	struct sheep_request *req;
+
+	write_lock(&dev->inflight_lock);
+	if (!list_empty(&dev->inflight_head)) {
+		req = list_first_entry(&dev->inflight_head, struct sheep_request, list);
+		list_del_init(&req->list);
+	} else
+		req = NULL;
+	write_unlock(&dev->inflight_lock);
+	return req;
+}
+
 static void submit_blocking_sheep_request(struct sbd_device *dev, uint64_t oid)
 {
 	struct sheep_request *req, *t;
@@ -637,6 +650,11 @@ int sheep_handle_reply(struct sbd_device *dev)
 	ret = socket_read(dev->sock, (char *)&rsp, sizeof(rsp));
 	if (ret < 0) {
 		pr_err("failed to read reply header %d\n", ret);
+		req = fetch_first_inflight_request(dev);
+		if (req != NULL) {
+			req->aiocb->ret = EIO;
+			goto end_request;
+		}
 		goto err;
 	}
 
-- 
2.1.0




More information about the sheepdog mailing list