aboutsummaryrefslogtreecommitdiffstats
path: root/fs/orangefs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-02-13 11:04:19 -0500
committerMike Marshall <hubcap@omnibond.com>2016-02-19 13:45:54 -0500
commit05b39a8b5cecaaf356497ee7df2f8acbc59eb2ee (patch)
treeaf3ba8ad03a4aaf49b3442df46712dd3c55bdf1c /fs/orangefs
parentc72f15b7d9b3cc744f066776dd0e61e6ab25e7d2 (diff)
orangefs: lift handling of timeouts and attempts count to service_operation()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs/orangefs')
-rw-r--r--fs/orangefs/waitqueue.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c
index 86b4b1fc0b14..378cdcf43252 100644
--- a/fs/orangefs/waitqueue.c
+++ b/fs/orangefs/waitqueue.c
@@ -16,7 +16,7 @@
16#include "orangefs-kernel.h" 16#include "orangefs-kernel.h"
17#include "orangefs-bufmap.h" 17#include "orangefs-bufmap.h"
18 18
19static int wait_for_matching_downcall(struct orangefs_kernel_op_s *, bool); 19static int wait_for_matching_downcall(struct orangefs_kernel_op_s *, long, bool);
20static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *); 20static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *);
21 21
22/* 22/*
@@ -55,6 +55,7 @@ int service_operation(struct orangefs_kernel_op_s *op,
55 const char *op_name, 55 const char *op_name,
56 int flags) 56 int flags)
57{ 57{
58 long timeout = MAX_SCHEDULE_TIMEOUT;
58 /* flags to modify behavior */ 59 /* flags to modify behavior */
59 int ret = 0; 60 int ret = 0;
60 61
@@ -102,15 +103,10 @@ retry_servicing:
102 spin_unlock(&op->lock); 103 spin_unlock(&op->lock);
103 wake_up_interruptible(&orangefs_request_list_waitq); 104 wake_up_interruptible(&orangefs_request_list_waitq);
104 if (!__is_daemon_in_service()) { 105 if (!__is_daemon_in_service()) {
105 /*
106 * By incrementing the per-operation attempt counter, we
107 * directly go into the timeout logic while waiting for
108 * the matching downcall to be read
109 */
110 gossip_debug(GOSSIP_WAIT_DEBUG, 106 gossip_debug(GOSSIP_WAIT_DEBUG,
111 "%s:client core is NOT in service.\n", 107 "%s:client core is NOT in service.\n",
112 __func__); 108 __func__);
113 op->attempts++; 109 timeout = op_timeout_secs * HZ;
114 } 110 }
115 spin_unlock(&orangefs_request_list_lock); 111 spin_unlock(&orangefs_request_list_lock);
116 112
@@ -124,33 +120,34 @@ retry_servicing:
124 if (flags & ORANGEFS_OP_ASYNC) 120 if (flags & ORANGEFS_OP_ASYNC)
125 return 0; 121 return 0;
126 122
127 ret = wait_for_matching_downcall(op, flags & ORANGEFS_OP_INTERRUPTIBLE); 123 ret = wait_for_matching_downcall(op, timeout,
128 124 flags & ORANGEFS_OP_INTERRUPTIBLE);
129 if (ret < 0) { 125 if (!ret) {
130 /* failed to get matching downcall */
131 if (ret == -ETIMEDOUT) {
132 gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n",
133 op_name);
134 }
135 orangefs_clean_up_interrupted_operation(op);
136 op->downcall.status = ret;
137 } else {
138 spin_unlock(&op->lock); 126 spin_unlock(&op->lock);
139 /* got matching downcall; make sure status is in errno format */ 127 /* got matching downcall; make sure status is in errno format */
140 op->downcall.status = 128 op->downcall.status =
141 orangefs_normalize_to_errno(op->downcall.status); 129 orangefs_normalize_to_errno(op->downcall.status);
142 ret = op->downcall.status; 130 ret = op->downcall.status;
131 goto out;
143 } 132 }
144 133
145 BUG_ON(ret != op->downcall.status); 134 /* failed to get matching downcall */
135 if (ret == -ETIMEDOUT) {
136 gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n",
137 op_name);
138 }
139 orangefs_clean_up_interrupted_operation(op);
140 op->downcall.status = ret;
146 /* retry if operation has not been serviced and if requested */ 141 /* retry if operation has not been serviced and if requested */
147 if (!op_state_serviced(op) && op->downcall.status == -EAGAIN) { 142 if (ret == -EAGAIN) {
143 op->attempts++;
144 timeout = op_timeout_secs * HZ;
148 gossip_debug(GOSSIP_WAIT_DEBUG, 145 gossip_debug(GOSSIP_WAIT_DEBUG,
149 "orangefs: tag %llu (%s)" 146 "orangefs: tag %llu (%s)"
150 " -- operation to be retried (%d attempt)\n", 147 " -- operation to be retried (%d attempt)\n",
151 llu(op->tag), 148 llu(op->tag),
152 op_name, 149 op_name,
153 op->attempts + 1); 150 op->attempts);
154 151
155 if (!op->uses_shared_memory) 152 if (!op->uses_shared_memory)
156 /* 153 /*
@@ -221,6 +218,7 @@ retry_servicing:
221 } 218 }
222 } 219 }
223 220
221out:
224 gossip_debug(GOSSIP_WAIT_DEBUG, 222 gossip_debug(GOSSIP_WAIT_DEBUG,
225 "orangefs: service_operation %s returning: %d for %p.\n", 223 "orangefs: service_operation %s returning: %d for %p.\n",
226 op_name, 224 op_name,
@@ -328,11 +326,10 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s
328 * Returns with op->lock taken. 326 * Returns with op->lock taken.
329 */ 327 */
330static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op, 328static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op,
329 long timeout,
331 bool interruptible) 330 bool interruptible)
332{ 331{
333 long timeout, n; 332 long n;
334
335 timeout = op->attempts ? op_timeout_secs * HZ : MAX_SCHEDULE_TIMEOUT;
336 333
337 if (interruptible) 334 if (interruptible)
338 n = wait_for_completion_interruptible_timeout(&op->waitq, timeout); 335 n = wait_for_completion_interruptible_timeout(&op->waitq, timeout);
@@ -354,7 +351,6 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op,
354 op); 351 op);
355 return -EINTR; 352 return -EINTR;
356 } 353 }
357 op->attempts++;
358 if (op_state_purged(op)) { 354 if (op_state_purged(op)) {
359 gossip_debug(GOSSIP_WAIT_DEBUG, 355 gossip_debug(GOSSIP_WAIT_DEBUG,
360 "*** %s:" 356 "*** %s:"