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

Commit ad3331ac authored by Trond Myklebust's avatar Trond Myklebust
Browse files

SUNRPC: Fix up socket autodisconnect



Ensure that we don't forget to set up the disconnection timer for the
case when a connect request is fulfilled after the RPC request that
initiated it has timed out or been interrupted.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 1f4c17a0
Loading
Loading
Loading
Loading
+18 −8
Original line number Original line Diff line number Diff line
@@ -680,6 +680,20 @@ void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie)
	spin_unlock_bh(&xprt->transport_lock);
	spin_unlock_bh(&xprt->transport_lock);
}
}


static bool
xprt_has_timer(const struct rpc_xprt *xprt)
{
	return xprt->idle_timeout != 0;
}

static void
xprt_schedule_autodisconnect(struct rpc_xprt *xprt)
	__must_hold(&xprt->transport_lock)
{
	if (list_empty(&xprt->recv) && xprt_has_timer(xprt))
		mod_timer(&xprt->timer, xprt->last_used + xprt->idle_timeout);
}

static void
static void
xprt_init_autodisconnect(unsigned long data)
xprt_init_autodisconnect(unsigned long data)
{
{
@@ -688,6 +702,8 @@ xprt_init_autodisconnect(unsigned long data)
	spin_lock(&xprt->transport_lock);
	spin_lock(&xprt->transport_lock);
	if (!list_empty(&xprt->recv))
	if (!list_empty(&xprt->recv))
		goto out_abort;
		goto out_abort;
	/* Reset xprt->last_used to avoid connect/autodisconnect cycling */
	xprt->last_used = jiffies;
	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
		goto out_abort;
		goto out_abort;
	spin_unlock(&xprt->transport_lock);
	spin_unlock(&xprt->transport_lock);
@@ -725,6 +741,7 @@ void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie)
		goto out;
		goto out;
	xprt->snd_task =NULL;
	xprt->snd_task =NULL;
	xprt->ops->release_xprt(xprt, NULL);
	xprt->ops->release_xprt(xprt, NULL);
	xprt_schedule_autodisconnect(xprt);
out:
out:
	spin_unlock_bh(&xprt->transport_lock);
	spin_unlock_bh(&xprt->transport_lock);
	wake_up_bit(&xprt->state, XPRT_LOCKED);
	wake_up_bit(&xprt->state, XPRT_LOCKED);
@@ -888,11 +905,6 @@ static void xprt_timer(struct rpc_task *task)
	spin_unlock_bh(&xprt->transport_lock);
	spin_unlock_bh(&xprt->transport_lock);
}
}


static inline int xprt_has_timer(struct rpc_xprt *xprt)
{
	return xprt->idle_timeout != 0;
}

/**
/**
 * xprt_prepare_transmit - reserve the transport before sending a request
 * xprt_prepare_transmit - reserve the transport before sending a request
 * @task: RPC task about to send a request
 * @task: RPC task about to send a request
@@ -1280,9 +1292,7 @@ void xprt_release(struct rpc_task *task)
	if (!list_empty(&req->rq_list))
	if (!list_empty(&req->rq_list))
		list_del(&req->rq_list);
		list_del(&req->rq_list);
	xprt->last_used = jiffies;
	xprt->last_used = jiffies;
	if (list_empty(&xprt->recv) && xprt_has_timer(xprt))
	xprt_schedule_autodisconnect(xprt);
		mod_timer(&xprt->timer,
				xprt->last_used + xprt->idle_timeout);
	spin_unlock_bh(&xprt->transport_lock);
	spin_unlock_bh(&xprt->transport_lock);
	if (req->rq_buffer)
	if (req->rq_buffer)
		xprt->ops->buf_free(req->rq_buffer);
		xprt->ops->buf_free(req->rq_buffer);