aboutsummaryrefslogtreecommitdiffstats
path: root/fs/orangefs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-02-13 10:15:22 -0500
committerMike Marshall <hubcap@omnibond.com>2016-02-19 13:45:53 -0500
commitd2d87a3b6df3088a991e277d42cd6a549ff2bc66 (patch)
tree7ca20690b8305a13283568762d2e2ab7b69574da /fs/orangefs
parentcf22644a0e5f1a66c61e90da15784effe3ba7ced (diff)
orangefs: get rid of loop in wait_for_matching_downcall()
turn op->waitq into struct completion... 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/orangefs-cache.c2
-rw-r--r--fs/orangefs/orangefs-kernel.h6
-rw-r--r--fs/orangefs/waitqueue.c129
3 files changed, 49 insertions, 88 deletions
diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c
index 59ab0c207e90..09194e69875f 100644
--- a/fs/orangefs/orangefs-cache.c
+++ b/fs/orangefs/orangefs-cache.c
@@ -118,7 +118,7 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type)
118 if (new_op) { 118 if (new_op) {
119 INIT_LIST_HEAD(&new_op->list); 119 INIT_LIST_HEAD(&new_op->list);
120 spin_lock_init(&new_op->lock); 120 spin_lock_init(&new_op->lock);
121 init_waitqueue_head(&new_op->waitq); 121 init_completion(&new_op->waitq);
122 122
123 atomic_set(&new_op->ref_count, 1); 123 atomic_set(&new_op->ref_count, 1);
124 124
diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h
index 3ceeeaed4143..de898bda7859 100644
--- a/fs/orangefs/orangefs-kernel.h
+++ b/fs/orangefs/orangefs-kernel.h
@@ -202,7 +202,7 @@ struct orangefs_kernel_op_s {
202 struct orangefs_upcall_s upcall; 202 struct orangefs_upcall_s upcall;
203 struct orangefs_downcall_s downcall; 203 struct orangefs_downcall_s downcall;
204 204
205 wait_queue_head_t waitq; 205 struct completion waitq;
206 spinlock_t lock; 206 spinlock_t lock;
207 207
208 struct completion done; 208 struct completion done;
@@ -222,7 +222,7 @@ struct orangefs_kernel_op_s {
222static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op) 222static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op)
223{ 223{
224 op->op_state = OP_VFS_STATE_SERVICED; 224 op->op_state = OP_VFS_STATE_SERVICED;
225 wake_up_interruptible(&op->waitq); 225 complete(&op->waitq);
226} 226}
227 227
228#define op_state_waiting(op) ((op)->op_state & OP_VFS_STATE_WAITING) 228#define op_state_waiting(op) ((op)->op_state & OP_VFS_STATE_WAITING)
@@ -266,7 +266,7 @@ static inline void set_op_state_purged(struct orangefs_kernel_op_s *op)
266 put_cancel(op); 266 put_cancel(op);
267 } else { 267 } else {
268 op->op_state |= OP_VFS_STATE_PURGED; 268 op->op_state |= OP_VFS_STATE_PURGED;
269 wake_up_interruptible(&op->waitq); 269 complete(&op->waitq);
270 spin_unlock(&op->lock); 270 spin_unlock(&op->lock);
271 } 271 }
272} 272}
diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c
index 3ea1665efdf0..89622717a06d 100644
--- a/fs/orangefs/waitqueue.c
+++ b/fs/orangefs/waitqueue.c
@@ -17,6 +17,7 @@
17#include "orangefs-bufmap.h" 17#include "orangefs-bufmap.h"
18 18
19static int wait_for_matching_downcall(struct orangefs_kernel_op_s *); 19static int wait_for_matching_downcall(struct orangefs_kernel_op_s *);
20static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *);
20 21
21/* 22/*
22 * What we do in this function is to walk the list of operations that are 23 * What we do in this function is to walk the list of operations that are
@@ -170,8 +171,10 @@ retry_servicing:
170 gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n", 171 gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n",
171 op_name); 172 op_name);
172 } 173 }
174 orangefs_clean_up_interrupted_operation(op);
173 op->downcall.status = ret; 175 op->downcall.status = ret;
174 } else { 176 } else {
177 spin_unlock(&op->lock);
175 /* got matching downcall; make sure status is in errno format */ 178 /* got matching downcall; make sure status is in errno format */
176 op->downcall.status = 179 op->downcall.status =
177 orangefs_normalize_to_errno(op->downcall.status); 180 orangefs_normalize_to_errno(op->downcall.status);
@@ -343,6 +346,7 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s
343 gossip_err("%s: can't get here.\n", __func__); 346 gossip_err("%s: can't get here.\n", __func__);
344 spin_unlock(&op->lock); 347 spin_unlock(&op->lock);
345 } 348 }
349 reinit_completion(&op->waitq);
346} 350}
347 351
348/* 352/*
@@ -359,95 +363,52 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s
359 * EINTR/EIO/ETIMEDOUT indicating we are done trying to service this 363 * EINTR/EIO/ETIMEDOUT indicating we are done trying to service this
360 * operation since client-core seems to be exiting too often 364 * operation since client-core seems to be exiting too often
361 * or if we were interrupted. 365 * or if we were interrupted.
366 *
367 * Returns with op->lock taken.
362 */ 368 */
363static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) 369static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op)
364{ 370{
365 int ret = -EINVAL; 371 long timeout, n;
366 DEFINE_WAIT(wait_entry);
367 372
368 while (1) { 373 timeout = op->attempts ? op_timeout_secs * HZ : MAX_SCHEDULE_TIMEOUT;
369 spin_lock(&op->lock); 374 n = wait_for_completion_interruptible_timeout(&op->waitq, timeout);
370 prepare_to_wait(&op->waitq, &wait_entry, TASK_INTERRUPTIBLE); 375 spin_lock(&op->lock);
371 if (op_state_serviced(op)) {
372 spin_unlock(&op->lock);
373 ret = 0;
374 break;
375 }
376 376
377 if (unlikely(signal_pending(current))) { 377 if (op_state_serviced(op))
378 gossip_debug(GOSSIP_WAIT_DEBUG, 378 return 0;
379 "*** %s:"
380 " operation interrupted by a signal (tag "
381 "%llu, op %p)\n",
382 __func__,
383 llu(op->tag),
384 op);
385 orangefs_clean_up_interrupted_operation(op);
386 ret = -EINTR;
387 break;
388 }
389 379
390 /* 380 if (unlikely(n < 0)) {
391 * if this was our first attempt and client-core 381 gossip_debug(GOSSIP_WAIT_DEBUG,
392 * has not purged our operation, we are happy to 382 "*** %s:"
393 * simply wait 383 " operation interrupted by a signal (tag "
394 */ 384 "%llu, op %p)\n",
395 if (op->attempts == 0 && !op_state_purged(op)) { 385 __func__,
396 spin_unlock(&op->lock); 386 llu(op->tag),
397 schedule(); 387 op);
398 } else { 388 return -EINTR;
399 spin_unlock(&op->lock);
400 /*
401 * subsequent attempts, we retry exactly once
402 * with timeouts
403 */
404 if (!schedule_timeout(op_timeout_secs * HZ)) {
405 gossip_debug(GOSSIP_WAIT_DEBUG,
406 "*** %s:"
407 " operation timed out (tag"
408 " %llu, %p, att %d)\n",
409 __func__,
410 llu(op->tag),
411 op,
412 op->attempts);
413 ret = -ETIMEDOUT;
414 spin_lock(&op->lock);
415 orangefs_clean_up_interrupted_operation(op);
416 break;
417 }
418 }
419 spin_lock(&op->lock);
420 op->attempts++;
421 /*
422 * if the operation was purged in the meantime, it
423 * is better to requeue it afresh but ensure that
424 * we have not been purged repeatedly. This could
425 * happen if client-core crashes when an op
426 * is being serviced, so we requeue the op, client
427 * core crashes again so we requeue the op, client
428 * core starts, and so on...
429 */
430 if (op_state_purged(op)) {
431 ret = (op->attempts < ORANGEFS_PURGE_RETRY_COUNT) ?
432 -EAGAIN :
433 -EIO;
434 gossip_debug(GOSSIP_WAIT_DEBUG,
435 "*** %s:"
436 " operation purged (tag "
437 "%llu, %p, att %d)\n",
438 __func__,
439 llu(op->tag),
440 op,
441 op->attempts);
442 orangefs_clean_up_interrupted_operation(op);
443 break;
444 }
445 spin_unlock(&op->lock);
446 } 389 }
447 390 op->attempts++;
448 spin_lock(&op->lock); 391 if (op_state_purged(op)) {
449 finish_wait(&op->waitq, &wait_entry); 392 gossip_debug(GOSSIP_WAIT_DEBUG,
450 spin_unlock(&op->lock); 393 "*** %s:"
451 394 " operation purged (tag "
452 return ret; 395 "%llu, %p, att %d)\n",
396 __func__,
397 llu(op->tag),
398 op,
399 op->attempts);
400 return (op->attempts < ORANGEFS_PURGE_RETRY_COUNT) ?
401 -EAGAIN :
402 -EIO;
403 }
404 /* must have timed out, then... */
405 gossip_debug(GOSSIP_WAIT_DEBUG,
406 "*** %s:"
407 " operation timed out (tag"
408 " %llu, %p, att %d)\n",
409 __func__,
410 llu(op->tag),
411 op,
412 op->attempts);
413 return -ETIMEDOUT;
453} 414}