diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-02-13 11:04:19 -0500 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2016-02-19 13:45:54 -0500 |
commit | 05b39a8b5cecaaf356497ee7df2f8acbc59eb2ee (patch) | |
tree | af3ba8ad03a4aaf49b3442df46712dd3c55bdf1c /fs/orangefs | |
parent | c72f15b7d9b3cc744f066776dd0e61e6ab25e7d2 (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.c | 46 |
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 | ||
19 | static int wait_for_matching_downcall(struct orangefs_kernel_op_s *, bool); | 19 | static int wait_for_matching_downcall(struct orangefs_kernel_op_s *, long, bool); |
20 | static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *); | 20 | static 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 | ||
221 | out: | ||
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 | */ |
330 | static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op, | 328 | static 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:" |