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>
This commit is contained in:
Al Viro 2016-02-13 11:04:19 -05:00 committed by Mike Marshall
parent c72f15b7d9
commit 05b39a8b5c
1 changed files with 21 additions and 25 deletions

View File

@ -16,7 +16,7 @@
#include "orangefs-kernel.h" #include "orangefs-kernel.h"
#include "orangefs-bufmap.h" #include "orangefs-bufmap.h"
static int wait_for_matching_downcall(struct orangefs_kernel_op_s *, bool); static int wait_for_matching_downcall(struct orangefs_kernel_op_s *, long, bool);
static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *); static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *);
/* /*
@ -55,6 +55,7 @@ int service_operation(struct orangefs_kernel_op_s *op,
const char *op_name, const char *op_name,
int flags) int flags)
{ {
long timeout = MAX_SCHEDULE_TIMEOUT;
/* flags to modify behavior */ /* flags to modify behavior */
int ret = 0; int ret = 0;
@ -102,15 +103,10 @@ int service_operation(struct orangefs_kernel_op_s *op,
spin_unlock(&op->lock); spin_unlock(&op->lock);
wake_up_interruptible(&orangefs_request_list_waitq); wake_up_interruptible(&orangefs_request_list_waitq);
if (!__is_daemon_in_service()) { if (!__is_daemon_in_service()) {
/*
* By incrementing the per-operation attempt counter, we
* directly go into the timeout logic while waiting for
* the matching downcall to be read
*/
gossip_debug(GOSSIP_WAIT_DEBUG, gossip_debug(GOSSIP_WAIT_DEBUG,
"%s:client core is NOT in service.\n", "%s:client core is NOT in service.\n",
__func__); __func__);
op->attempts++; timeout = op_timeout_secs * HZ;
} }
spin_unlock(&orangefs_request_list_lock); spin_unlock(&orangefs_request_list_lock);
@ -124,33 +120,34 @@ int service_operation(struct orangefs_kernel_op_s *op,
if (flags & ORANGEFS_OP_ASYNC) if (flags & ORANGEFS_OP_ASYNC)
return 0; return 0;
ret = wait_for_matching_downcall(op, flags & ORANGEFS_OP_INTERRUPTIBLE); ret = wait_for_matching_downcall(op, timeout,
flags & ORANGEFS_OP_INTERRUPTIBLE);
if (ret < 0) { if (!ret) {
/* failed to get matching downcall */
if (ret == -ETIMEDOUT) {
gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n",
op_name);
}
orangefs_clean_up_interrupted_operation(op);
op->downcall.status = ret;
} else {
spin_unlock(&op->lock); spin_unlock(&op->lock);
/* got matching downcall; make sure status is in errno format */ /* got matching downcall; make sure status is in errno format */
op->downcall.status = op->downcall.status =
orangefs_normalize_to_errno(op->downcall.status); orangefs_normalize_to_errno(op->downcall.status);
ret = op->downcall.status; ret = op->downcall.status;
goto out;
} }
BUG_ON(ret != op->downcall.status); /* failed to get matching downcall */
if (ret == -ETIMEDOUT) {
gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n",
op_name);
}
orangefs_clean_up_interrupted_operation(op);
op->downcall.status = ret;
/* retry if operation has not been serviced and if requested */ /* retry if operation has not been serviced and if requested */
if (!op_state_serviced(op) && op->downcall.status == -EAGAIN) { if (ret == -EAGAIN) {
op->attempts++;
timeout = op_timeout_secs * HZ;
gossip_debug(GOSSIP_WAIT_DEBUG, gossip_debug(GOSSIP_WAIT_DEBUG,
"orangefs: tag %llu (%s)" "orangefs: tag %llu (%s)"
" -- operation to be retried (%d attempt)\n", " -- operation to be retried (%d attempt)\n",
llu(op->tag), llu(op->tag),
op_name, op_name,
op->attempts + 1); op->attempts);
if (!op->uses_shared_memory) if (!op->uses_shared_memory)
/* /*
@ -221,6 +218,7 @@ int service_operation(struct orangefs_kernel_op_s *op,
} }
} }
out:
gossip_debug(GOSSIP_WAIT_DEBUG, gossip_debug(GOSSIP_WAIT_DEBUG,
"orangefs: service_operation %s returning: %d for %p.\n", "orangefs: service_operation %s returning: %d for %p.\n",
op_name, op_name,
@ -328,11 +326,10 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s
* Returns with op->lock taken. * Returns with op->lock taken.
*/ */
static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op, static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op,
long timeout,
bool interruptible) bool interruptible)
{ {
long timeout, n; long n;
timeout = op->attempts ? op_timeout_secs * HZ : MAX_SCHEDULE_TIMEOUT;
if (interruptible) if (interruptible)
n = wait_for_completion_interruptible_timeout(&op->waitq, timeout); 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,
op); op);
return -EINTR; return -EINTR;
} }
op->attempts++;
if (op_state_purged(op)) { if (op_state_purged(op)) {
gossip_debug(GOSSIP_WAIT_DEBUG, gossip_debug(GOSSIP_WAIT_DEBUG,
"*** %s:" "*** %s:"