Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05b39a8b authored by Al Viro's avatar Al Viro Committed by Mike Marshall
Browse files

orangefs: lift handling of timeouts and attempts count to service_operation()

parent c72f15b7
Loading
Loading
Loading
Loading
+21 −25
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
#include "orangefs-kernel.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 *);

/*
@@ -55,6 +55,7 @@ int service_operation(struct orangefs_kernel_op_s *op,
		      const char *op_name,
		      int flags)
{
	long timeout = MAX_SCHEDULE_TIMEOUT;
	/* flags to modify behavior */
	int ret = 0;

@@ -102,15 +103,10 @@ int service_operation(struct orangefs_kernel_op_s *op,
	spin_unlock(&op->lock);
	wake_up_interruptible(&orangefs_request_list_waitq);
	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,
			     "%s:client core is NOT in service.\n",
			     __func__);
		op->attempts++;
		timeout = op_timeout_secs * HZ;
	}
	spin_unlock(&orangefs_request_list_lock);

@@ -124,9 +120,17 @@ int service_operation(struct orangefs_kernel_op_s *op,
	if (flags & ORANGEFS_OP_ASYNC)
		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) {
		spin_unlock(&op->lock);
		/* got matching downcall; make sure status is in errno format */
		op->downcall.status =
		    orangefs_normalize_to_errno(op->downcall.status);
		ret = op->downcall.status;
		goto out;
	}

	if (ret < 0) {
	/* failed to get matching downcall */
	if (ret == -ETIMEDOUT) {
		gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n",
@@ -134,23 +138,16 @@ int service_operation(struct orangefs_kernel_op_s *op,
	}
	orangefs_clean_up_interrupted_operation(op);
	op->downcall.status = ret;
	} else {
		spin_unlock(&op->lock);
		/* got matching downcall; make sure status is in errno format */
		op->downcall.status =
		    orangefs_normalize_to_errno(op->downcall.status);
		ret = op->downcall.status;
	}

	BUG_ON(ret != op->downcall.status);
	/* 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,
			     "orangefs: tag %llu (%s)"
			     " -- operation to be retried (%d attempt)\n",
			     llu(op->tag),
			     op_name,
			     op->attempts + 1);
			     op->attempts);

		if (!op->uses_shared_memory)
			/*
@@ -221,6 +218,7 @@ int service_operation(struct orangefs_kernel_op_s *op,
		}
	}

out:
	gossip_debug(GOSSIP_WAIT_DEBUG,
		     "orangefs: service_operation %s returning: %d for %p.\n",
		     op_name,
@@ -328,11 +326,10 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s
 * Returns with op->lock taken.
 */
static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op,
				      long timeout,
				      bool interruptible)
{
	long timeout, n;

	timeout = op->attempts ? op_timeout_secs * HZ : MAX_SCHEDULE_TIMEOUT;
	long n;

	if (interruptible)
		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);
		return -EINTR;
	}
	op->attempts++;
	if (op_state_purged(op)) {
		gossip_debug(GOSSIP_WAIT_DEBUG,
			     "*** %s:"