summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-04-28 17:07:26 +0300
committerIlya Dryomov <idryomov@gmail.com>2016-05-26 02:14:06 +0300
commit42b0696527c49a109e9558162b8d109ae257d402 (patch)
tree59f4168f0f6d2a11738d3f2f213df5e363799f53 /net
parent3540bfdb30fcb423a92cc959708e71bc39eb18c3 (diff)
downloadlinux-42b0696527c49a109e9558162b8d109ae257d402.tar.xz
libceph: wait_request_timeout()
The unwatch timeout is currently implemented in rbd. With watch/unwatch code moving into libceph, we are going to need a ceph_osdc_wait_request() variant with a timeout. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/osd_client.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 46e6fb5a1299..ef1bcbe9af2d 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -2668,28 +2668,36 @@ void ceph_osdc_cancel_request(struct ceph_osd_request *req)
EXPORT_SYMBOL(ceph_osdc_cancel_request);
/*
- * wait for a request to complete
+ * @timeout: in jiffies, 0 means "wait forever"
*/
-int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
- struct ceph_osd_request *req)
+static int wait_request_timeout(struct ceph_osd_request *req,
+ unsigned long timeout)
{
- int rc;
-
- dout("%s %p tid %llu\n", __func__, req, req->r_tid);
+ long left;
- rc = wait_for_completion_interruptible(&req->r_completion);
- if (rc < 0) {
- dout("%s %p tid %llu interrupted\n", __func__, req, req->r_tid);
+ dout("%s req %p tid %llu\n", __func__, req, req->r_tid);
+ left = wait_for_completion_interruptible_timeout(&req->r_completion,
+ ceph_timeout_jiffies(timeout));
+ if (left <= 0) {
+ left = left ?: -ETIMEDOUT;
ceph_osdc_cancel_request(req);
/* kludge - need to to wake ceph_osdc_sync() */
complete_all(&req->r_safe_completion);
- return rc;
+ } else {
+ left = req->r_result; /* completed */
}
- dout("%s %p tid %llu result %d\n", __func__, req, req->r_tid,
- req->r_result);
- return req->r_result;
+ return left;
+}
+
+/*
+ * wait for a request to complete
+ */
+int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req)
+{
+ return wait_request_timeout(req, 0);
}
EXPORT_SYMBOL(ceph_osdc_wait_request);