// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/net/sunrpc/xprt.c
 *
 *  This is a generic RPC call interface supporting congestion avoidance,
 *  and asynchronous calls.
 *
 *  The interface works like this:
 *
 *  -	When a process places a call, it allocates a request slot if
 *	one is available. Otherwise, it sleeps on the backlog queue
 *	(xprt_reserve).
 *  -	Next, the caller puts together the RPC message, stuffs it into
 *	the request struct, and calls xprt_transmit().
 *  -	xprt_transmit sends the message and installs the caller on the
 *	transport's wait list. At the same time, if a reply is expected,
 *	it installs a timer that is run after the packet's timeout has
 *	expired.
 *  -	When a packet arrives, the data_ready handler walks the list of
 *	pending requests for that transport. If a matching XID is found, the
 *	caller is woken up, and the timer removed.
 *  -	When no reply arrives within the timeout interval, the timer is
 *	fired by the kernel and runs xprt_timer(). It either adjusts the
 *	timeout values (minor timeout) or wakes up the caller with a status
 *	of -ETIMEDOUT.
 *  -	When the caller receives a notification from RPC that a reply arrived,
 *	it should release the RPC slot, and process the reply.
 *	If the call timed out, it may choose to retry the operation by
 *	adjusting the initial timeout value, and simply calling rpc_call
 *	again.
 *
 *  Support for async RPC is done through a set of RPC-specific scheduling
 *  primitives that `transparently' work for processes as well as async
 *  tasks that rely on callbacks.
 *
 *  Copyright (C) 1995-1997, Olaf Kirch <okir@monad.swb.de>
 *
 *  Transport switch API copyright (C) 2005, Chuck Lever <cel@netapp.com>
 */

#include <linux/module.h>

#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/net.h>
#include <linux/ktime.h>

#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/metrics.h>
#include <linux/sunrpc/bc_xprt.h>
#include <linux/rcupdate.h>
#include <linux/sched/mm.h>

#include <trace/events/sunrpc.h>

#include "sunrpc.h"
#include "sysfs.h"
#include "fail.h"

/*
 * Local variables
 */

#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
# define RPCDBG_FACILITY	RPCDBG_XPRT
#endif

/*
 * Local functions
 */
static void	xprt_init(struct rpc_xprt *xprt, struct net *net);
static __be32	xprt_alloc_xid(struct rpc_xprt *xprt);
static void	xprt_destroy(struct rpc_xprt *xprt);
static void	xprt_request_init(struct rpc_task *task);
static int	xprt_request_prepare(struct rpc_rqst *req, struct xdr_buf *buf);

static DEFINE_SPINLOCK(xprt_list_lock);
static LIST_HEAD(xprt_list);

static unsigned long xprt_request_timeout(const struct rpc_rqst *req)
{
	unsigned long timeout = jiffies + req->rq_timeout;

	if (time_before(timeout, req->rq_majortimeo))
		return timeout;
	return req->rq_majortimeo;
}

/**
 * xprt_register_transport - register a transport implementation
 * @transport: transport to register
 *
 * If a transport implementation is loaded as a kernel module, it can
 * call this interface to make itself known to the RPC client.
 *
 * Returns:
 * 0:		transport successfully registered
 * -EEXIST:	transport already registered
 * -EINVAL:	transport module being unloaded
 */
int xprt_register_transport(struct xprt_class *transport)
{
	struct xprt_class *t;
	int result;

	result = -EEXIST;
	spin_lock(&xprt_list_lock);
	list_for_each_entry(t, &xprt_list, list) {
		/* don't register the same transport class twice */
		if (t->ident == transport->ident)
			goto out;
	}

	list_add_tail(&transport->list, &xprt_list);
	printk(KERN_INFO "RPC: Registered %s transport module.\n",
	       transport->name);
	result = 0;

out:
	spin_unlock(&xprt_list_lock);
	return result;
}
EXPORT_SYMBOL_GPL(xprt_register_transport);

/**
 * xprt_unregister_transport - unregister a transport implementation
 * @transport: transport to unregister
 *
 * Returns:
 * 0:		transport successfully unregistered
 * -ENOENT:	transport never registered
 */
int xprt_unregister_transport(struct xprt_class *transport)
{
	struct xprt_class *t;
	int result;

	result = 0;
	spin_lock(&xprt_list_lock);
	list_for_each_entry(t, &xprt_list, list) {
		if (t == transport) {
			printk(KERN_INFO
				"RPC: Unregistered %s transport module.\n",
				transport->name);
			list_del_init(&transport->list);
			goto out;
		}
	}
	result = -ENOENT;

out:
	spin_unlock(&xprt_list_lock);
	return result;
}
EXPORT_SYMBOL_GPL(xprt_unregister_transport);

static void
xprt_class_release(const struct xprt_class *t)
{
	module_put(t->owner);
}

static const struct xprt_class *
xprt_class_find_by_ident_locked(int ident)
{
	const struct xprt_class *t;

	list_for_each_entry(t, &xprt_list, list) {
		if (t->ident != ident)
			continue;
		if (!try_module_get(t->owner))
			continue;
		return t;
	}
	return NULL;
}

static const struct xprt_class *
xprt_class_find_by_ident(int ident)
{
	const struct xprt_class *t;

	spin_lock(&xprt_list_lock);
	t = xprt_class_find_by_ident_locked(ident);
	spin_unlock(&xprt_list_lock);
	return t;
}

static const struct xprt_class *
xprt_class_find_by_netid_locked(const char *netid)
{
	const struct xprt_class *t;
	unsigned int i;

	list_for_each_entry(t, &xprt_list, list) {
		for (i = 0; t->netid[i][0] != '\0'; i++) {
			if (strcmp(t->netid[i], netid) != 0)
				continue;
			if (!try_module_get(t->owner))
				continue;
			return t;
		}
	}
	return NULL;
}

static const struct xprt_class *
xprt_class_find_by_netid(const char *netid)
{
	const struct xprt_class *t;

	spin_lock(&xprt_list_lock);
	t = xprt_class_find_by_netid_locked(netid);
	if (!t) {
		spin_unlock(&xprt_list_lock);
		request_module("rpc%s", netid);
		spin_lock(&xprt_list_lock);
		t = xprt_class_find_by_netid_locked(netid);
	}
	spin_unlock(&xprt_list_lock);
	return t;
}

/**
 * xprt_find_transport_ident - convert a netid into a transport identifier
 * @netid: transport to load
 *
 * Returns:
 * > 0:		transport identifier
 * -ENOENT:	transport module not available
 */
int xprt_find_transport_ident(const char *netid)
{
	const struct xprt_class *t;
	int ret;

	t = xprt_class_find_by_netid(netid);
	if (!t)
		return -ENOENT;
	ret = t->ident;
	xprt_class_release(t);
	return ret;
}
EXPORT_SYMBOL_GPL(xprt_find_transport_ident);

static void xprt_clear_locked(struct rpc_xprt *xprt)
{
	xprt->snd_task = NULL;
	if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state))
		clear_bit_unlock(XPRT_LOCKED, &xprt->state);
	else
		queue_work(xprtiod_workqueue, &xprt->task_cleanup);
}

/**
 * xprt_reserve_xprt - serialize write access to transports
 * @task: task that is requesting access to the transport
 * @xprt: pointer to the target transport
 *
 * This prevents mixing the payload of separate requests, and prevents
 * transport connects from colliding with writes.  No congestion control
 * is provided.
 */
int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;

	if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
		if (task == xprt->snd_task)
			goto out_locked;
		goto out_sleep;
	}
	if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
		goto out_unlock;
	xprt->snd_task = task;

out_locked:
	trace_xprt_reserve_xprt(xprt, task);
	return 1;

out_unlock:
	xprt_clear_locked(xprt);
out_sleep:
	task->tk_status = -EAGAIN;
	if (RPC_IS_SOFT(task) || RPC_IS_SOFTCONN(task))
		rpc_sleep_on_timeout(&xprt->sending, task, NULL,
				xprt_request_timeout(req));
	else
		rpc_sleep_on(&xprt->sending, task, NULL);
	return 0;
}
EXPORT_SYMBOL_GPL(xprt_reserve_xprt);

static bool
xprt_need_congestion_window_wait(struct rpc_xprt *xprt)
{
	return test_bit(XPRT_CWND_WAIT, &xprt->state);
}

static void
xprt_set_congestion_window_wait(struct rpc_xprt *xprt)
{
	if (!list_empty(&xprt->xmit_queue)) {
		/* Peek at head of queue to see if it can make progress */
		if (list_first_entry(&xprt->xmit_queue, struct rpc_rqst,
					rq_xmit)->rq_cong)
			return;
	}
	set_bit(XPRT_CWND_WAIT, &xprt->state);
}

static void
xprt_test_and_clear_congestion_window_wait(struct rpc_xprt *xprt)
{
	if (!RPCXPRT_CONGESTED(xprt))
		clear_bit(XPRT_CWND_WAIT, &xprt->state);
}

/*
 * xprt_reserve_xprt_cong - serialize write access to transports
 * @task: task that is requesting access to the transport
 *
 * Same as xprt_reserve_xprt, but Van Jacobson congestion control is
 * integrated into the decision of whether a request is allowed to be
 * woken up and given access to the transport.
 * Note that the lock is only granted if we know there are free slots.
 */
int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;

	if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
		if (task == xprt->snd_task)
			goto out_locked;
		goto out_sleep;
	}
	if (req == NULL) {
		xprt->snd_task = task;
		goto out_locked;
	}
	if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
		goto out_unlock;
	if (!xprt_need_congestion_window_wait(xprt)) {
		xprt->snd_task = task;
		goto out_locked;
	}
out_unlock:
	xprt_clear_locked(xprt);
out_sleep:
	task->tk_status = -EAGAIN;
	if (RPC_IS_SOFT(task) || RPC_IS_SOFTCONN(task))
		rpc_sleep_on_timeout(&xprt->sending, task, NULL,
				xprt_request_timeout(req));
	else
		rpc_sleep_on(&xprt->sending, task, NULL);
	return 0;
out_locked:
	trace_xprt_reserve_cong(xprt, task);
	return 1;
}
EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);

static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
	int retval;

	if (test_bit(XPRT_LOCKED, &xprt->state) && xprt->snd_task == task)
		return 1;
	spin_lock(&xprt->transport_lock);
	retval = xprt->ops->reserve_xprt(xprt, task);
	spin_unlock(&xprt->transport_lock);
	return retval;
}

static bool __xprt_lock_write_func(struct rpc_task *task, void *data)
{
	struct rpc_xprt *xprt = data;

	xprt->snd_task = task;
	return true;
}

static void __xprt_lock_write_next(struct rpc_xprt *xprt)
{
	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
		return;
	if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
		goto out_unlock;
	if (rpc_wake_up_first_on_wq(xprtiod_workqueue, &xprt->sending,
				__xprt_lock_write_func, xprt))
		return;
out_unlock:
	xprt_clear_locked(xprt);
}

static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
{
	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
		return;
	if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
		goto out_unlock;
	if (xprt_need_congestion_window_wait(xprt))
		goto out_unlock;
	if (rpc_wake_up_first_on_wq(xprtiod_workqueue, &xprt->sending,
				__xprt_lock_write_func, xprt))
		return;
out_unlock:
	xprt_clear_locked(xprt);
}

/**
 * xprt_release_xprt - allow other requests to use a transport
 * @xprt: transport with other tasks potentially waiting
 * @task: task that is releasing access to the transport
 *
 * Note that "task" can be NULL.  No congestion control is provided.
 */
void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
{
	if (xprt->snd_task == task) {
		xprt_clear_locked(xprt);
		__xprt_lock_write_next(xprt);
	}
	trace_xprt_release_xprt(xprt, task);
}
EXPORT_SYMBOL_GPL(xprt_release_xprt);

/**
 * xprt_release_xprt_cong - allow other requests to use a transport
 * @xprt: transport with other tasks potentially waiting
 * @task: task that is releasing access to the transport
 *
 * Note that "task" can be NULL.  Another task is awoken to use the
 * transport if the transport's congestion window allows it.
 */
void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
{
	if (xprt->snd_task == task) {
		xprt_clear_locked(xprt);
		__xprt_lock_write_next_cong(xprt);
	}
	trace_xprt_release_cong(xprt, task);
}
EXPORT_SYMBOL_GPL(xprt_release_xprt_cong);

void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
	if (xprt->snd_task != task)
		return;
	spin_lock(&xprt->transport_lock);
	xprt->ops->release_xprt(xprt, task);
	spin_unlock(&xprt->transport_lock);
}

/*
 * Van Jacobson congestion avoidance. Check if the congestion window
 * overflowed. Put the task to sleep if this is the case.
 */
static int
__xprt_get_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	if (req->rq_cong)
		return 1;
	trace_xprt_get_cong(xprt, req->rq_task);
	if (RPCXPRT_CONGESTED(xprt)) {
		xprt_set_congestion_window_wait(xprt);
		return 0;
	}
	req->rq_cong = 1;
	xprt->cong += RPC_CWNDSCALE;
	return 1;
}

/*
 * Adjust the congestion window, and wake up the next task
 * that has been sleeping due to congestion
 */
static void
__xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	if (!req->rq_cong)
		return;
	req->rq_cong = 0;
	xprt->cong -= RPC_CWNDSCALE;
	xprt_test_and_clear_congestion_window_wait(xprt);
	trace_xprt_put_cong(xprt, req->rq_task);
	__xprt_lock_write_next_cong(xprt);
}

/**
 * xprt_request_get_cong - Request congestion control credits
 * @xprt: pointer to transport
 * @req: pointer to RPC request
 *
 * Useful for transports that require congestion control.
 */
bool
xprt_request_get_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	bool ret = false;

	if (req->rq_cong)
		return true;
	spin_lock(&xprt->transport_lock);
	ret = __xprt_get_cong(xprt, req) != 0;
	spin_unlock(&xprt->transport_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(xprt_request_get_cong);

/**
 * xprt_release_rqst_cong - housekeeping when request is complete
 * @task: RPC request that recently completed
 *
 * Useful for transports that require congestion control.
 */
void xprt_release_rqst_cong(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;

	__xprt_put_cong(req->rq_xprt, req);
}
EXPORT_SYMBOL_GPL(xprt_release_rqst_cong);

static void xprt_clear_congestion_window_wait_locked(struct rpc_xprt *xprt)
{
	if (test_and_clear_bit(XPRT_CWND_WAIT, &xprt->state))
		__xprt_lock_write_next_cong(xprt);
}

/*
 * Clear the congestion window wait flag and wake up the next
 * entry on xprt->sending
 */
static void
xprt_clear_congestion_window_wait(struct rpc_xprt *xprt)
{
	if (test_and_clear_bit(XPRT_CWND_WAIT, &xprt->state)) {
		spin_lock(&xprt->transport_lock);
		__xprt_lock_write_next_cong(xprt);
		spin_unlock(&xprt->transport_lock);
	}
}

/**
 * xprt_adjust_cwnd - adjust transport congestion window
 * @xprt: pointer to xprt
 * @task: recently completed RPC request used to adjust window
 * @result: result code of completed RPC request
 *
 * The transport code maintains an estimate on the maximum number of out-
 * standing RPC requests, using a smoothed version of the congestion
 * avoidance implemented in 44BSD. This is basically the Van Jacobson
 * congestion algorithm: If a retransmit occurs, the congestion window is
 * halved; otherwise, it is incremented by 1/cwnd when
 *
 *	-	a reply is received and
 *	-	a full number of requests are outstanding and
 *	-	the congestion window hasn't been updated recently.
 */
void xprt_adjust_cwnd(struct rpc_xprt *xprt, struct rpc_task *task, int result)
{
	struct rpc_rqst *req = task->tk_rqstp;
	unsigned long cwnd = xprt->cwnd;

	if (result >= 0 && cwnd <= xprt->cong) {
		/* The (cwnd >> 1) term makes sure
		 * the result gets rounded properly. */
		cwnd += (RPC_CWNDSCALE * RPC_CWNDSCALE + (cwnd >> 1)) / cwnd;
		if (cwnd > RPC_MAXCWND(xprt))
			cwnd = RPC_MAXCWND(xprt);
		__xprt_lock_write_next_cong(xprt);
	} else if (result == -ETIMEDOUT) {
		cwnd >>= 1;
		if (cwnd < RPC_CWNDSCALE)
			cwnd = RPC_CWNDSCALE;
	}
	dprintk("RPC:       cong %ld, cwnd was %ld, now %ld\n",
			xprt->cong, xprt->cwnd, cwnd);
	xprt->cwnd = cwnd;
	__xprt_put_cong(xprt, req);
}
EXPORT_SYMBOL_GPL(xprt_adjust_cwnd);

/**
 * xprt_wake_pending_tasks - wake all tasks on a transport's pending queue
 * @xprt: transport with waiting tasks
 * @status: result code to plant in each task before waking it
 *
 */
void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status)
{
	if (status < 0)
		rpc_wake_up_status(&xprt->pending, status);
	else
		rpc_wake_up(&xprt->pending);
}
EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);

/**
 * xprt_wait_for_buffer_space - wait for transport output buffer to clear
 * @xprt: transport
 *
 * Note that we only set the timer for the case of RPC_IS_SOFT(), since
 * we don't in general want to force a socket disconnection due to
 * an incomplete RPC call transmission.
 */
void xprt_wait_for_buffer_space(struct rpc_xprt *xprt)
{
	set_bit(XPRT_WRITE_SPACE, &xprt->state);
}
EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);

static bool
xprt_clear_write_space_locked(struct rpc_xprt *xprt)
{
	if (test_and_clear_bit(XPRT_WRITE_SPACE, &xprt->state)) {
		__xprt_lock_write_next(xprt);
		dprintk("RPC:       write space: waking waiting task on "
				"xprt %p\n", xprt);
		return true;
	}
	return false;
}

/**
 * xprt_write_space - wake the task waiting for transport output buffer space
 * @xprt: transport with waiting tasks
 *
 * Can be called in a soft IRQ context, so xprt_write_space never sleeps.
 */
bool xprt_write_space(struct rpc_xprt *xprt)
{
	bool ret;

	if (!test_bit(XPRT_WRITE_SPACE, &xprt->state))
		return false;
	spin_lock(&xprt->transport_lock);
	ret = xprt_clear_write_space_locked(xprt);
	spin_unlock(&xprt->transport_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(xprt_write_space);

static unsigned long xprt_abs_ktime_to_jiffies(ktime_t abstime)
{
	s64 delta = ktime_to_ns(ktime_get() - abstime);
	return likely(delta >= 0) ?
		jiffies - nsecs_to_jiffies(delta) :
		jiffies + nsecs_to_jiffies(-delta);
}

static unsigned long xprt_calc_majortimeo(struct rpc_rqst *req,
		const struct rpc_timeout *to)
{
	unsigned long majortimeo = req->rq_timeout;

	if (to->to_exponential)
		majortimeo <<= to->to_retries;
	else
		majortimeo += to->to_increment * to->to_retries;
	if (majortimeo > to->to_maxval || majortimeo == 0)
		majortimeo = to->to_maxval;
	return majortimeo;
}

static void xprt_reset_majortimeo(struct rpc_rqst *req,
		const struct rpc_timeout *to)
{
	req->rq_majortimeo += xprt_calc_majortimeo(req, to);
}

static void xprt_reset_minortimeo(struct rpc_rqst *req)
{
	req->rq_minortimeo += req->rq_timeout;
}

static void xprt_init_majortimeo(struct rpc_task *task, struct rpc_rqst *req,
		const struct rpc_timeout *to)
{
	unsigned long time_init;
	struct rpc_xprt *xprt = req->rq_xprt;

	if (likely(xprt && xprt_connected(xprt)))
		time_init = jiffies;
	else
		time_init = xprt_abs_ktime_to_jiffies(task->tk_start);

	req->rq_timeout = to->to_initval;
	req->rq_majortimeo = time_init + xprt_calc_majortimeo(req, to);
	req->rq_minortimeo = time_init + req->rq_timeout;
}

/**
 * xprt_adjust_timeout - adjust timeout values for next retransmit
 * @req: RPC request containing parameters to use for the adjustment
 *
 */
int xprt_adjust_timeout(struct rpc_rqst *req)
{
	struct rpc_xprt *xprt = req->rq_xprt;
	const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout;
	int status = 0;

	if (time_before(jiffies, req->rq_majortimeo)) {
		if (time_before(jiffies, req->rq_minortimeo))
			return status;
		if (to->to_exponential)
			req->rq_timeout <<= 1;
		else
			req->rq_timeout += to->to_increment;
		if (to->to_maxval && req->rq_timeout >= to->to_maxval)
			req->rq_timeout = to->to_maxval;
		req->rq_retries++;
	} else {
		req->rq_timeout = to->to_initval;
		req->rq_retries = 0;
		xprt_reset_majortimeo(req, to);
		/* Reset the RTT counters == "slow start" */
		spin_lock(&xprt->transport_lock);
		rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval);
		spin_unlock(&xprt->transport_lock);
		status = -ETIMEDOUT;
	}
	xprt_reset_minortimeo(req);

	if (req->rq_timeout == 0) {
		printk(KERN_WARNING "xprt_adjust_timeout: rq_timeout = 0!\n");
		req->rq_timeout = 5 * HZ;
	}
	return status;
}

static void xprt_autoclose(struct work_struct *work)
{
	struct rpc_xprt *xprt =
		container_of(work, struct rpc_xprt, task_cleanup);
	unsigned int pflags = memalloc_nofs_save();

	trace_xprt_disconnect_auto(xprt);
	xprt->connect_cookie++;
	smp_mb__before_atomic();
	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
	xprt->ops->close(xprt);
	xprt_release_write(xprt, NULL);
	wake_up_bit(&xprt->state, XPRT_LOCKED);
	memalloc_nofs_restore(pflags);
}

/**
 * xprt_disconnect_done - mark a transport as disconnected
 * @xprt: transport to flag for disconnect
 *
 */
void xprt_disconnect_done(struct rpc_xprt *xprt)
{
	trace_xprt_disconnect_done(xprt);
	spin_lock(&xprt->transport_lock);
	xprt_clear_connected(xprt);
	xprt_clear_write_space_locked(xprt);
	xprt_clear_congestion_window_wait_locked(xprt);
	xprt_wake_pending_tasks(xprt, -ENOTCONN);
	spin_unlock(&xprt->transport_lock);
}
EXPORT_SYMBOL_GPL(xprt_disconnect_done);

/**
 * xprt_schedule_autoclose_locked - Try to schedule an autoclose RPC call
 * @xprt: transport to disconnect
 */
static void xprt_schedule_autoclose_locked(struct rpc_xprt *xprt)
{
	if (test_and_set_bit(XPRT_CLOSE_WAIT, &xprt->state))
		return;
	if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
		queue_work(xprtiod_workqueue, &xprt->task_cleanup);
	else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state))
		rpc_wake_up_queued_task_set_status(&xprt->pending,
						   xprt->snd_task, -ENOTCONN);
}

/**
 * xprt_force_disconnect - force a transport to disconnect
 * @xprt: transport to disconnect
 *
 */
void xprt_force_disconnect(struct rpc_xprt *xprt)
{
	trace_xprt_disconnect_force(xprt);

	/* Don't race with the test_bit() in xprt_clear_locked() */
	spin_lock(&xprt->transport_lock);
	xprt_schedule_autoclose_locked(xprt);
	spin_unlock(&xprt->transport_lock);
}
EXPORT_SYMBOL_GPL(xprt_force_disconnect);

static unsigned int
xprt_connect_cookie(struct rpc_xprt *xprt)
{
	return READ_ONCE(xprt->connect_cookie);
}

static bool
xprt_request_retransmit_after_disconnect(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;

	return req->rq_connect_cookie != xprt_connect_cookie(xprt) ||
		!xprt_connected(xprt);
}

/**
 * xprt_conditional_disconnect - force a transport to disconnect
 * @xprt: transport to disconnect
 * @cookie: 'connection cookie'
 *
 * This attempts to break the connection if and only if 'cookie' matches
 * the current transport 'connection cookie'. It ensures that we don't
 * try to break the connection more than once when we need to retransmit
 * a batch of RPC requests.
 *
 */
void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie)
{
	/* Don't race with the test_bit() in xprt_clear_locked() */
	spin_lock(&xprt->transport_lock);
	if (cookie != xprt->connect_cookie)
		goto out;
	if (test_bit(XPRT_CLOSING, &xprt->state))
		goto out;
	xprt_schedule_autoclose_locked(xprt);
out:
	spin_unlock(&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)
{
	xprt->last_used = jiffies;
	if (RB_EMPTY_ROOT(&xprt->recv_queue) && xprt_has_timer(xprt))
		mod_timer(&xprt->timer, xprt->last_used + xprt->idle_timeout);
}

static void
xprt_init_autodisconnect(struct timer_list *t)
{
	struct rpc_xprt *xprt = from_timer(xprt, t, timer);

	if (!RB_EMPTY_ROOT(&xprt->recv_queue))
		return;
	/* Reset xprt->last_used to avoid connect/autodisconnect cycling */
	xprt->last_used = jiffies;
	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
		return;
	queue_work(xprtiod_workqueue, &xprt->task_cleanup);
}

#if IS_ENABLED(CONFIG_FAIL_SUNRPC)
static void xprt_inject_disconnect(struct rpc_xprt *xprt)
{
	if (!fail_sunrpc.ignore_client_disconnect &&
	    should_fail(&fail_sunrpc.attr, 1))
		xprt->ops->inject_disconnect(xprt);
}
#else
static inline void xprt_inject_disconnect(struct rpc_xprt *xprt)
{
}
#endif

bool xprt_lock_connect(struct rpc_xprt *xprt,
		struct rpc_task *task,
		void *cookie)
{
	bool ret = false;

	spin_lock(&xprt->transport_lock);
	if (!test_bit(XPRT_LOCKED, &xprt->state))
		goto out;
	if (xprt->snd_task != task)
		goto out;
	set_bit(XPRT_SND_IS_COOKIE, &xprt->state);
	xprt->snd_task = cookie;
	ret = true;
out:
	spin_unlock(&xprt->transport_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(xprt_lock_connect);

void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie)
{
	spin_lock(&xprt->transport_lock);
	if (xprt->snd_task != cookie)
		goto out;
	if (!test_bit(XPRT_LOCKED, &xprt->state))
		goto out;
	xprt->snd_task =NULL;
	clear_bit(XPRT_SND_IS_COOKIE, &xprt->state);
	xprt->ops->release_xprt(xprt, NULL);
	xprt_schedule_autodisconnect(xprt);
out:
	spin_unlock(&xprt->transport_lock);
	wake_up_bit(&xprt->state, XPRT_LOCKED);
}
EXPORT_SYMBOL_GPL(xprt_unlock_connect);

/**
 * xprt_connect - schedule a transport connect operation
 * @task: RPC task that is requesting the connect
 *
 */
void xprt_connect(struct rpc_task *task)
{
	struct rpc_xprt	*xprt = task->tk_rqstp->rq_xprt;

	trace_xprt_connect(xprt);

	if (!xprt_bound(xprt)) {
		task->tk_status = -EAGAIN;
		return;
	}
	if (!xprt_lock_write(xprt, task))
		return;

	if (!xprt_connected(xprt) && !test_bit(XPRT_CLOSE_WAIT, &xprt->state)) {
		task->tk_rqstp->rq_connect_cookie = xprt->connect_cookie;
		rpc_sleep_on_timeout(&xprt->pending, task, NULL,
				xprt_request_timeout(task->tk_rqstp));

		if (test_bit(XPRT_CLOSING, &xprt->state))
			return;
		if (xprt_test_and_set_connecting(xprt))
			return;
		/* Race breaker */
		if (!xprt_connected(xprt)) {
			xprt->stat.connect_start = jiffies;
			xprt->ops->connect(xprt, task);
		} else {
			xprt_clear_connecting(xprt);
			task->tk_status = 0;
			rpc_wake_up_queued_task(&xprt->pending, task);
		}
	}
	xprt_release_write(xprt, task);
}

/**
 * xprt_reconnect_delay - compute the wait before scheduling a connect
 * @xprt: transport instance
 *
 */
unsigned long xprt_reconnect_delay(const struct rpc_xprt *xprt)
{
	unsigned long start, now = jiffies;

	start = xprt->stat.connect_start + xprt->reestablish_timeout;
	if (time_after(start, now))
		return start - now;
	return 0;
}
EXPORT_SYMBOL_GPL(xprt_reconnect_delay);

/**
 * xprt_reconnect_backoff - compute the new re-establish timeout
 * @xprt: transport instance
 * @init_to: initial reestablish timeout
 *
 */
void xprt_reconnect_backoff(struct rpc_xprt *xprt, unsigned long init_to)
{
	xprt->reestablish_timeout <<= 1;
	if (xprt->reestablish_timeout > xprt->max_reconnect_timeout)
		xprt->reestablish_timeout = xprt->max_reconnect_timeout;
	if (xprt->reestablish_timeout < init_to)
		xprt->reestablish_timeout = init_to;
}
EXPORT_SYMBOL_GPL(xprt_reconnect_backoff);

enum xprt_xid_rb_cmp {
	XID_RB_EQUAL,
	XID_RB_LEFT,
	XID_RB_RIGHT,
};
static enum xprt_xid_rb_cmp
xprt_xid_cmp(__be32 xid1, __be32 xid2)
{
	if (xid1 == xid2)
		return XID_RB_EQUAL;
	if ((__force u32)xid1 < (__force u32)xid2)
		return XID_RB_LEFT;
	return XID_RB_RIGHT;
}

static struct rpc_rqst *
xprt_request_rb_find(struct rpc_xprt *xprt, __be32 xid)
{
	struct rb_node *n = xprt->recv_queue.rb_node;
	struct rpc_rqst *req;

	while (n != NULL) {
		req = rb_entry(n, struct rpc_rqst, rq_recv);
		switch (xprt_xid_cmp(xid, req->rq_xid)) {
		case XID_RB_LEFT:
			n = n->rb_left;
			break;
		case XID_RB_RIGHT:
			n = n->rb_right;
			break;
		case XID_RB_EQUAL:
			return req;
		}
	}
	return NULL;
}

static void
xprt_request_rb_insert(struct rpc_xprt *xprt, struct rpc_rqst *new)
{
	struct rb_node **p = &xprt->recv_queue.rb_node;
	struct rb_node *n = NULL;
	struct rpc_rqst *req;

	while (*p != NULL) {
		n = *p;
		req = rb_entry(n, struct rpc_rqst, rq_recv);
		switch(xprt_xid_cmp(new->rq_xid, req->rq_xid)) {
		case XID_RB_LEFT:
			p = &n->rb_left;
			break;
		case XID_RB_RIGHT:
			p = &n->rb_right;
			break;
		case XID_RB_EQUAL:
			WARN_ON_ONCE(new != req);
			return;
		}
	}
	rb_link_node(&new->rq_recv, n, p);
	rb_insert_color(&new->rq_recv, &xprt->recv_queue);
}

static void
xprt_request_rb_remove(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	rb_erase(&req->rq_recv, &xprt->recv_queue);
}

/**
 * xprt_lookup_rqst - find an RPC request corresponding to an XID
 * @xprt: transport on which the original request was transmitted
 * @xid: RPC XID of incoming reply
 *
 * Caller holds xprt->queue_lock.
 */
struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
{
	struct rpc_rqst *entry;

	entry = xprt_request_rb_find(xprt, xid);
	if (entry != NULL) {
		trace_xprt_lookup_rqst(xprt, xid, 0);
		entry->rq_rtt = ktime_sub(ktime_get(), entry->rq_xtime);
		return entry;
	}

	dprintk("RPC:       xprt_lookup_rqst did not find xid %08x\n",
			ntohl(xid));
	trace_xprt_lookup_rqst(xprt, xid, -ENOENT);
	xprt->stat.bad_xids++;
	return NULL;
}
EXPORT_SYMBOL_GPL(xprt_lookup_rqst);

static bool
xprt_is_pinned_rqst(struct rpc_rqst *req)
{
	return atomic_read(&req->rq_pin) != 0;
}

/**
 * xprt_pin_rqst - Pin a request on the transport receive list
 * @req: Request to pin
 *
 * Caller must ensure this is atomic with the call to xprt_lookup_rqst()
 * so should be holding xprt->queue_lock.
 */
void xprt_pin_rqst(struct rpc_rqst *req)
{
	atomic_inc(&req->rq_pin);
}
EXPORT_SYMBOL_GPL(xprt_pin_rqst);

/**
 * xprt_unpin_rqst - Unpin a request on the transport receive list
 * @req: Request to pin
 *
 * Caller should be holding xprt->queue_lock.
 */
void xprt_unpin_rqst(struct rpc_rqst *req)
{
	if (!test_bit(RPC_TASK_MSG_PIN_WAIT, &req->rq_task->tk_runstate)) {
		atomic_dec(&req->rq_pin);
		return;
	}
	if (atomic_dec_and_test(&req->rq_pin))
		wake_up_var(&req->rq_pin);
}
EXPORT_SYMBOL_GPL(xprt_unpin_rqst);

static void xprt_wait_on_pinned_rqst(struct rpc_rqst *req)
{
	wait_var_event(&req->rq_pin, !xprt_is_pinned_rqst(req));
}

static bool
xprt_request_data_received(struct rpc_task *task)
{
	return !test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate) &&
		READ_ONCE(task->tk_rqstp->rq_reply_bytes_recvd) != 0;
}

static bool
xprt_request_need_enqueue_receive(struct rpc_task *task, struct rpc_rqst *req)
{
	return !test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate) &&
		READ_ONCE(task->tk_rqstp->rq_reply_bytes_recvd) == 0;
}

/**
 * xprt_request_enqueue_receive - Add an request to the receive queue
 * @task: RPC task
 *
 */
int
xprt_request_enqueue_receive(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;
	int ret;

	if (!xprt_request_need_enqueue_receive(task, req))
		return 0;

	ret = xprt_request_prepare(task->tk_rqstp, &req->rq_rcv_buf);
	if (ret)
		return ret;
	spin_lock(&xprt->queue_lock);

	/* Update the softirq receive buffer */
	memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
			sizeof(req->rq_private_buf));

	/* Add request to the receive list */
	xprt_request_rb_insert(xprt, req);
	set_bit(RPC_TASK_NEED_RECV, &task->tk_runstate);
	spin_unlock(&xprt->queue_lock);

	/* Turn off autodisconnect */
	del_timer_sync(&xprt->timer);
	return 0;
}

/**
 * xprt_request_dequeue_receive_locked - Remove a request from the receive queue
 * @task: RPC task
 *
 * Caller must hold xprt->queue_lock.
 */
static void
xprt_request_dequeue_receive_locked(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;

	if (test_and_clear_bit(RPC_TASK_NEED_RECV, &task->tk_runstate))
		xprt_request_rb_remove(req->rq_xprt, req);
}

/**
 * xprt_update_rtt - Update RPC RTT statistics
 * @task: RPC request that recently completed
 *
 * Caller holds xprt->queue_lock.
 */
void xprt_update_rtt(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_rtt *rtt = task->tk_client->cl_rtt;
	unsigned int timer = task->tk_msg.rpc_proc->p_timer;
	long m = usecs_to_jiffies(ktime_to_us(req->rq_rtt));

	if (timer) {
		if (req->rq_ntrans == 1)
			rpc_update_rtt(rtt, timer, m);
		rpc_set_timeo(rtt, timer, req->rq_ntrans - 1);
	}
}
EXPORT_SYMBOL_GPL(xprt_update_rtt);

/**
 * xprt_complete_rqst - called when reply processing is complete
 * @task: RPC request that recently completed
 * @copied: actual number of bytes received from the transport
 *
 * Caller holds xprt->queue_lock.
 */
void xprt_complete_rqst(struct rpc_task *task, int copied)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;

	xprt->stat.recvs++;

	xdr_free_bvec(&req->rq_rcv_buf);
	req->rq_private_buf.bvec = NULL;
	req->rq_private_buf.len = copied;
	/* Ensure all writes are done before we update */
	/* req->rq_reply_bytes_recvd */
	smp_wmb();
	req->rq_reply_bytes_recvd = copied;
	xprt_request_dequeue_receive_locked(task);
	rpc_wake_up_queued_task(&xprt->pending, task);
}
EXPORT_SYMBOL_GPL(xprt_complete_rqst);

static void xprt_timer(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;

	if (task->tk_status != -ETIMEDOUT)
		return;

	trace_xprt_timer(xprt, req->rq_xid, task->tk_status);
	if (!req->rq_reply_bytes_recvd) {
		if (xprt->ops->timer)
			xprt->ops->timer(xprt, task);
	} else
		task->tk_status = 0;
}

/**
 * xprt_wait_for_reply_request_def - wait for reply
 * @task: pointer to rpc_task
 *
 * Set a request's retransmit timeout based on the transport's
 * default timeout parameters.  Used by transports that don't adjust
 * the retransmit timeout based on round-trip time estimation,
 * and put the task to sleep on the pending queue.
 */
void xprt_wait_for_reply_request_def(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;

	rpc_sleep_on_timeout(&req->rq_xprt->pending, task, xprt_timer,
			xprt_request_timeout(req));
}
EXPORT_SYMBOL_GPL(xprt_wait_for_reply_request_def);

/**
 * xprt_wait_for_reply_request_rtt - wait for reply using RTT estimator
 * @task: pointer to rpc_task
 *
 * Set a request's retransmit timeout using the RTT estimator,
 * and put the task to sleep on the pending queue.
 */
void xprt_wait_for_reply_request_rtt(struct rpc_task *task)
{
	int timer = task->tk_msg.rpc_proc->p_timer;
	struct rpc_clnt *clnt = task->tk_client;
	struct rpc_rtt *rtt = clnt->cl_rtt;
	struct rpc_rqst *req = task->tk_rqstp;
	unsigned long max_timeout = clnt->cl_timeout->to_maxval;
	unsigned long timeout;

	timeout = rpc_calc_rto(rtt, timer);
	timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries;
	if (timeout > max_timeout || timeout == 0)
		timeout = max_timeout;
	rpc_sleep_on_timeout(&req->rq_xprt->pending, task, xprt_timer,
			jiffies + timeout);
}
EXPORT_SYMBOL_GPL(xprt_wait_for_reply_request_rtt);

/**
 * xprt_request_wait_receive - wait for the reply to an RPC request
 * @task: RPC task about to send a request
 *
 */
void xprt_request_wait_receive(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;

	if (!test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate))
		return;
	/*
	 * Sleep on the pending queue if we're expecting a reply.
	 * The spinlock ensures atomicity between the test of
	 * req->rq_reply_bytes_recvd, and the call to rpc_sleep_on().
	 */
	spin_lock(&xprt->queue_lock);
	if (test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate)) {
		xprt->ops->wait_for_reply_request(task);
		/*
		 * Send an extra queue wakeup call if the
		 * connection was dropped in case the call to
		 * rpc_sleep_on() raced.
		 */
		if (xprt_request_retransmit_after_disconnect(task))
			rpc_wake_up_queued_task_set_status(&xprt->pending,
					task, -ENOTCONN);
	}
	spin_unlock(&xprt->queue_lock);
}

static bool
xprt_request_need_enqueue_transmit(struct rpc_task *task, struct rpc_rqst *req)
{
	return !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate);
}

/**
 * xprt_request_enqueue_transmit - queue a task for transmission
 * @task: pointer to rpc_task
 *
 * Add a task to the transmission queue.
 */
void
xprt_request_enqueue_transmit(struct rpc_task *task)
{
	struct rpc_rqst *pos, *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;
	int ret;

	if (xprt_request_need_enqueue_transmit(task, req)) {
		ret = xprt_request_prepare(task->tk_rqstp, &req->rq_snd_buf);
		if (ret) {
			task->tk_status = ret;
			return;
		}
		req->rq_bytes_sent = 0;
		spin_lock(&xprt->queue_lock);
		/*
		 * Requests that carry congestion control credits are added
		 * to the head of the list to avoid starvation issues.
		 */
		if (req->rq_cong) {
			xprt_clear_congestion_window_wait(xprt);
			list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
				if (pos->rq_cong)
					continue;
				/* Note: req is added _before_ pos */
				list_add_tail(&req->rq_xmit, &pos->rq_xmit);
				INIT_LIST_HEAD(&req->rq_xmit2);
				goto out;
			}
		} else if (!req->rq_seqno) {
			list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
				if (pos->rq_task->tk_owner != task->tk_owner)
					continue;
				list_add_tail(&req->rq_xmit2, &pos->rq_xmit2);
				INIT_LIST_HEAD(&req->rq_xmit);
				goto out;
			}
		}
		list_add_tail(&req->rq_xmit, &xprt->xmit_queue);
		INIT_LIST_HEAD(&req->rq_xmit2);
out:
		atomic_long_inc(&xprt->xmit_queuelen);
		set_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate);
		spin_unlock(&xprt->queue_lock);
	}
}

/**
 * xprt_request_dequeue_transmit_locked - remove a task from the transmission queue
 * @task: pointer to rpc_task
 *
 * Remove a task from the transmission queue
 * Caller must hold xprt->queue_lock
 */
static void
xprt_request_dequeue_transmit_locked(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;

	if (!test_and_clear_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
		return;
	if (!list_empty(&req->rq_xmit)) {
		struct rpc_xprt *xprt = req->rq_xprt;

		if (list_is_first(&req->rq_xmit, &xprt->xmit_queue) &&
		    xprt->ops->abort_send_request)
			xprt->ops->abort_send_request(req);

		list_del(&req->rq_xmit);
		if (!list_empty(&req->rq_xmit2)) {
			struct rpc_rqst *next = list_first_entry(&req->rq_xmit2,
					struct rpc_rqst, rq_xmit2);
			list_del(&req->rq_xmit2);
			list_add_tail(&next->rq_xmit, &next->rq_xprt->xmit_queue);
		}
	} else
		list_del(&req->rq_xmit2);
	atomic_long_dec(&req->rq_xprt->xmit_queuelen);
	xdr_free_bvec(&req->rq_snd_buf);
}

/**
 * xprt_request_dequeue_transmit - remove a task from the transmission queue
 * @task: pointer to rpc_task
 *
 * Remove a task from the transmission queue
 */
static void
xprt_request_dequeue_transmit(struct rpc_task *task)
{
	struct rpc_rqst *req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;

	spin_lock(&xprt->queue_lock);
	xprt_request_dequeue_transmit_locked(task);
	spin_unlock(&xprt->queue_lock);
}

/**
 * xprt_request_dequeue_xprt - remove a task from the transmit+receive queue
 * @task: pointer to rpc_task
 *
 * Remove a task from the transmit and receive queues, and ensure that
 * it is not pinned by the receive work item.
 */
void
xprt_request_dequeue_xprt(struct rpc_task *task)
{
	struct rpc_rqst	*req = task->tk_rqstp;
	struct rpc_xprt *xprt = req->rq_xprt;

	if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate) ||
	    test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate) ||
	    xprt_is_pinned_rqst(req)) {
		spin_lock(&xprt->queue_lock);
		while (xprt_is_pinned_rqst(req)) {
			set_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate);
			spin_unlock(&xprt->queue_lock);
			xprt_wait_on_pinned_rqst(req);
			spin_lock(&xprt->queue_lock);
			clear_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate);
		}
		xprt_request_dequeue_transmit_locked(task);
		xprt_request_dequeue_receive_locked(task);
		spin_unlock(&xprt->queue_lock);
		xdr_free_bvec(&req->rq_rcv_buf);
	}
}

/**
 * xprt_request_prepare - prepare an encoded request for transport
 * @req: pointer to rpc_rqst
 * @buf: pointer to send/rcv xdr_buf
 *
 * Calls into the transport layer to do whatever is needed to prepare
 * the request for transmission or receive.
 * Returns error, or zero.
 */
static int
xprt_request_prepare(struct rpc_rqst *req, struct xdr_buf *buf)
{
	struct rpc_xprt *xprt = req->rq_xprt;

	if (xprt->ops->prepare_request)
		return xprt->ops->prepare_request(req, buf);
	return 0;
}

/**
 * xprt_request_need_retransmit - Test if a task needs retransmission
 * @task: pointer to rpc_task
 *
 * Test for whether a connection breakage requires the task to retransmit
 */
bool
xprt_request_need_retransmit(struct rpc_task *task)
{
	return xprt_request_retransmit_after_disconnect(task);
}

/**
 * xprt_prepare_transmit - reserve the transport before sending a request
 * @task: RPC task about to send a request
 *
 */
bool xprt_prepare_transmit(struct rpc_task *task)
{
	struct rpc_rqst	*req = task->tk_rqstp;
	struct rpc_xprt	*xprt = req->rq_xprt;

	if (!xprt_lock_write(xprt, task)) {
		/* Race breaker: someone may have transmitted us */
		if (!test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
			rpc_wake_up_queued_task_set_status(&xprt->sending,
					task, 0);
		return false;

	}
	if (atomic_read(&xprt->swapper))
		/* This will be clear in __rpc_execute */
		current->flags |= PF_MEMALLOC;
	return true;
}

void xprt_end_transmit(struct rpc_task *task)
{
	struct rpc_xprt	*xprt = task->tk_rqstp->rq_xprt;

	xprt_inject_disconnect(xprt);
	xprt_release_write(xprt, task);
}

/**
 * xprt_request_transmit - send an RPC request on a transport
 * @req: pointer to request to transmit
 * @snd_task: RPC task that owns the transport lock
 *
 * This performs the transmission of a single request.
 * Note that if the request is not the same as snd_task, then it
 * does need to be pinned.
 * Returns '0' on success.
 */
static int
xprt_request_transmit(struct rpc_rqst *req, struct rpc_task *snd_task)
{
	struct rpc_xprt *xprt = req->rq_xprt;
	struct rpc_task *task = req->rq_task;
	unsigned int connect_cookie;
	int is_retrans = RPC_WAS_SENT(task);
	int status;

	if (test_bit(XPRT_CLOSE_WAIT, &xprt->state))
		return -ENOTCONN;

	if (!req->rq_bytes_sent) {
		if (xprt_request_data_received(task)) {
			status = 0;
			goto out_dequeue;
		}
		/* Verify that our message lies in the RPCSEC_GSS window */
		if (rpcauth_xmit_need_reencode(task)) {
			status = -EBADMSG;
			goto out_dequeue;
		}
		if (RPC_SIGNALLED(task)) {
			status = -ERESTARTSYS;
			goto out_dequeue;
		}
	}

	/*
	 * Update req->rq_ntrans before transmitting to avoid races with
	 * xprt_update_rtt(), which needs to know that it is recording a
	 * reply to the first transmission.
	 */
	req->rq_ntrans++;

	trace_rpc_xdr_sendto(task, &req->rq_snd_buf);
	connect_cookie = xprt->connect_cookie;
	status = xprt->ops->send_request(req);
	if (status != 0) {
		req->rq_ntrans--;
		trace_xprt_transmit(req, status);
		return status;
	}

	if (is_retrans) {
		task->tk_client->cl_stats->rpcretrans++;
		trace_xprt_retransmit(req);
	}

	xprt_inject_disconnect(xprt);

	task->tk_flags |= RPC_TASK_SENT;
	spin_lock(&xprt->transport_lock);

	xprt->stat.sends++;
	xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
	xprt->stat.bklog_u += xprt->backlog.qlen;
	xprt->stat.sending_u += xprt->sending.qlen;
	xprt->stat.pending_u += xprt->pending.qlen;
	spin_unlock(&xprt->transport_lock);

	req->rq_connect_cookie = connect_cookie;
out_dequeue:
	trace_xprt_transmit(req, status);
	xprt_request_dequeue_transmit(task);
	rpc_wake_up_queued_task_set_status(&xprt->sending, task, status);
	return status;
}

/**
 * xprt_transmit - send an RPC request on a transport
 * @task: controlling RPC task
 *
 * Attempts to drain the transmit queue. On exit, either the transport
 * signalled an error that needs to be handled before transmission can
 * resume, or @task finished transmitting, and detected that it already
 * received a reply.
 */
void
xprt_transmit(struct rpc_task *task)
{
	struct rpc_rqst *next, *req = task->tk_rqstp;
	struct rpc_xprt	*xprt = req->rq_xprt;
	int status;

	spin_lock(&xprt->queue_lock);
	for (;;) {
		next = list_first_entry_or_null(&xprt->xmit_queue,
						struct rpc_rqst, rq_xmit);
		if (!next)
			break;
		xprt_pin_rqst(next);
		spin_unlock(&xprt->queue_lock);
		status = xprt_request_transmit(next, task);
		if (status == -EBADMSG && next != req)
			status = 0;
		spin_lock(&xprt->queue_lock);
		xprt_unpin_rqst(next);
		if (status < 0) {
			if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
				task->tk_status = status;
			break;
		}
		/* Was @task transmitted, and has it received a reply? */
		if (xprt_request_data_received(task) &&
		    !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
			break;
		cond_resched_lock(&xprt->queue_lock);
	}
	spin_unlock(&xprt->queue_lock);
}

static void xprt_complete_request_init(struct rpc_task *task)
{
	if (task->tk_rqstp)
		xprt_request_init(task);
}

void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task)
{
	set_bit(XPRT_CONGESTED, &xprt->state);
	rpc_sleep_on(&xprt->backlog, task, xprt_complete_request_init);
}
EXPORT_SYMBOL_GPL(xprt_add_backlog);

static bool __xprt_set_rq(struct rpc_task *task, void *data)
{
	struct rpc_rqst *req = data;

	if (task->tk_rqstp == NULL) {
		memset(req, 0, sizeof(*req));	/* mark unused */
		task->tk_rqstp = req;
		return true;
	}
	return false;
}

bool xprt_wake_up_backlog(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	if (rpc_wake_up_first(&xprt->backlog, __xprt_set_rq, req) == NULL) {
		clear_bit(XPRT_CONGESTED, &xprt->state);
		return false;
	}
	return true;
}
EXPORT_SYMBOL_GPL(xprt_wake_up_backlog);

static bool xprt_throttle_congested(struct rpc_xprt *xprt, struct rpc_task *task)
{
	bool ret = false;

	if (!test_bit(XPRT_CONGESTED, &xprt->state))
		goto out;
	spin_lock(&xprt->reserve_lock);
	if (test_bit(XPRT_CONGESTED, &xprt->state)) {
		xprt_add_backlog(xprt, task);
		ret = true;
	}
	spin_unlock(&xprt->reserve_lock);
out:
	return ret;
}

static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt)
{
	struct rpc_rqst *req = ERR_PTR(-EAGAIN);

	if (xprt->num_reqs >= xprt->max_reqs)
		goto out;
	++xprt->num_reqs;
	spin_unlock(&xprt->reserve_lock);
	req = kzalloc(sizeof(*req), rpc_task_gfp_mask());
	spin_lock(&xprt->reserve_lock);
	if (req != NULL)
		goto out;
	--xprt->num_reqs;
	req = ERR_PTR(-ENOMEM);
out:
	return req;
}

static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	if (xprt->num_reqs > xprt->min_reqs) {
		--xprt->num_reqs;
		kfree(req);
		return true;
	}
	return false;
}

void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)
{
	struct rpc_rqst *req;

	spin_lock(&xprt->reserve_lock);
	if (!list_empty(&xprt->free)) {
		req = list_entry(xprt->free.next, struct rpc_rqst, rq_list);
		list_del(&req->rq_list);
		goto out_init_req;
	}
	req = xprt_dynamic_alloc_slot(xprt);
	if (!IS_ERR(req))
		goto out_init_req;
	switch (PTR_ERR(req)) {
	case -ENOMEM:
		dprintk("RPC:       dynamic allocation of request slot "
				"failed! Retrying\n");
		task->tk_status = -ENOMEM;
		break;
	case -EAGAIN:
		xprt_add_backlog(xprt, task);
		dprintk("RPC:       waiting for request slot\n");
		fallthrough;
	default:
		task->tk_status = -EAGAIN;
	}
	spin_unlock(&xprt->reserve_lock);
	return;
out_init_req:
	xprt->stat.max_slots = max_t(unsigned int, xprt->stat.max_slots,
				     xprt->num_reqs);
	spin_unlock(&xprt->reserve_lock);

	task->tk_status = 0;
	task->tk_rqstp = req;
}
EXPORT_SYMBOL_GPL(xprt_alloc_slot);

void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
	spin_lock(&xprt->reserve_lock);
	if (!xprt_wake_up_backlog(xprt, req) &&
	    !xprt_dynamic_free_slot(xprt, req)) {
		memset(req, 0, sizeof(*req));	/* mark unused */
		list_add(&req->rq_list, &xprt->free);
	}
	spin_unlock(&xprt->reserve_lock);
}
EXPORT_SYMBOL_GPL(xprt_free_slot);

static void xprt_free_all_slots(struct rpc_xprt *xprt)
{
	struct rpc_rqst *req;
	while (!list_empty(&xprt->free)) {
		req = list_first_entry(&xprt->free, struct rpc_rqst, rq_list);
		list_del(&req->rq_list);
		kfree(req);
	}
}

static DEFINE_IDA(rpc_xprt_ids);

void xprt_cleanup_ids(void)
{
	ida_destroy(&rpc_xprt_ids);
}

static int xprt_alloc_id(struct rpc_xprt *xprt)
{
	int id;

	id = ida_alloc(&rpc_xprt_ids, GFP_KERNEL);
	if (id < 0)
		return id;

	xprt->id = id;
	return 0;
}

static void xprt_free_id(struct rpc_xprt *xprt)
{
	ida_free(&rpc_xprt_ids, xprt->id);
}

struct rpc_xprt *xprt_alloc(struct net *net, size_t size,
		unsigned int num_prealloc,
		unsigned int max_alloc)
{
	struct rpc_xprt *xprt;
	struct rpc_rqst *req;
	int i;

	xprt = kzalloc(size, GFP_KERNEL);
	if (xprt == NULL)
		goto out;

	xprt_alloc_id(xprt);
	xprt_init(xprt, net);

	for (i = 0; i < num_prealloc; i++) {
		req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL);
		if (!req)
			goto out_free;
		list_add(&req->rq_list, &xprt->free);
	}
	xprt->max_reqs = max_t(unsigned int, max_alloc, num_prealloc);
	xprt->min_reqs = num_prealloc;
	xprt->num_reqs = num_prealloc;

	return xprt;

out_free:
	xprt_free(xprt);
out:
	return NULL;
}
EXPORT_SYMBOL_GPL(xprt_alloc);

void xprt_free(struct rpc_xprt *xprt)
{
	put_net_track(xprt->xprt_net, &xprt->ns_tracker);
	xprt_free_all_slots(xprt);
	xprt_free_id(xprt);
	rpc_sysfs_xprt_destroy(xprt);
	kfree_rcu(xprt, rcu);
}
EXPORT_SYMBOL_GPL(xprt_free);

static void
xprt_init_connect_cookie(struct rpc_rqst *req, struct rpc_xprt *xprt)
{
	req->rq_connect_cookie = xprt_connect_cookie(xprt) - 1;
}

static __be32
xprt_alloc_xid(struct rpc_xprt *xprt)
{
	__be32 xid;

	spin_lock(&xprt->reserve_lock);
	xid = (__force __be32)xprt->xid++;
	spin_unlock(&xprt->reserve_lock);
	return xid;
}

static void
xprt_init_xid(struct rpc_xprt *xprt)
{
	xprt->xid = get_random_u32();
}

static void
xprt_request_init(struct rpc_task *task)
{
	struct rpc_xprt *xprt = task->tk_xprt;
	struct rpc_rqst	*req = task->tk_rqstp;

	req->rq_task	= task;
	req->rq_xprt    = xprt;
	req->rq_buffer  = NULL;
	req->rq_xid	= xprt_alloc_xid(xprt);
	xprt_init_connect_cookie(req, xprt);
	req->rq_snd_buf.len = 0;
	req->rq_snd_buf.buflen = 0;
	req->rq_rcv_buf.len = 0;
	req->rq_rcv_buf.buflen = 0;
	req->rq_snd_buf.bvec = NULL;
	req->rq_rcv_buf.bvec = NULL;
	req->rq_release_snd_buf = NULL;
	xprt_init_majortimeo(task, req, task->tk_client->cl_timeout);

	trace_xprt_reserve(req);
}

static void
xprt_do_reserve(struct rpc_xprt *xprt, struct rpc_task *task)
{
	xprt->ops->alloc_slot(xprt, task);
	if (task->tk_rqstp != NULL)
		xprt_request_init(task);
}

/**
 * xprt_reserve - allocate an RPC request slot
 * @task: RPC task requesting a slot allocation
 *
 * If the transport is marked as being congested, or if no more
 * slots are available, place the task on the transport's
 * backlog queue.
 */
void xprt_reserve(struct rpc_task *task)
{
	struct rpc_xprt *xprt = task->tk_xprt;

	task->tk_status = 0;
	if (task->tk_rqstp != NULL)
		return;

	task->tk_status = -EAGAIN;
	if (!xprt_throttle_congested(xprt, task))
		xprt_do_reserve(xprt, task);
}

/**
 * xprt_retry_reserve - allocate an RPC request slot
 * @task: RPC task requesting a slot allocation
 *
 * If no more slots are available, place the task on the transport's
 * backlog queue.
 * Note that the only difference with xprt_reserve is that we now
 * ignore the value of the XPRT_CONGESTED flag.
 */
void xprt_retry_reserve(struct rpc_task *task)
{
	struct rpc_xprt *xprt = task->tk_xprt;

	task->tk_status = 0;
	if (task->tk_rqstp != NULL)
		return;

	task->tk_status = -EAGAIN;
	xprt_do_reserve(xprt, task);
}

/**
 * xprt_release - release an RPC request slot
 * @task: task which is finished with the slot
 *
 */
void xprt_release(struct rpc_task *task)
{
	struct rpc_xprt	*xprt;
	struct rpc_rqst	*req = task->tk_rqstp;

	if (req == NULL) {
		if (task->tk_client) {
			xprt = task->tk_xprt;
			xprt_release_write(xprt, task);
		}
		return;
	}

	xprt = req->rq_xprt;
	xprt_request_dequeue_xprt(task);
	spin_lock(&xprt->transport_lock);
	xprt->ops->release_xprt(xprt, task);
	if (xprt->ops->release_request)
		xprt->ops->release_request(task);
	xprt_schedule_autodisconnect(xprt);
	spin_unlock(&xprt->transport_lock);
	if (req->rq_buffer)
		xprt->ops->buf_free(task);
	if (req->rq_cred != NULL)
		put_rpccred(req->rq_cred);
	if (req->rq_release_snd_buf)
		req->rq_release_snd_buf(req);

	task->tk_rqstp = NULL;
	if (likely(!bc_prealloc(req)))
		xprt->ops->free_slot(xprt, req);
	else
		xprt_free_bc_request(req);
}

#ifdef CONFIG_SUNRPC_BACKCHANNEL
void
xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task,
		const struct rpc_timeout *to)
{
	struct xdr_buf *xbufp = &req->rq_snd_buf;

	task->tk_rqstp = req;
	req->rq_task = task;
	xprt_init_connect_cookie(req, req->rq_xprt);
	/*
	 * Set up the xdr_buf length.
	 * This also indicates that the buffer is XDR encoded already.
	 */
	xbufp->len = xbufp->head[0].iov_len + xbufp->page_len +
		xbufp->tail[0].iov_len;
	/*
	 * Backchannel Replies are sent with !RPC_TASK_SOFT and
	 * RPC_TASK_NO_RETRANS_TIMEOUT. The major timeout setting
	 * affects only how long each Reply waits to be sent when
	 * a transport connection cannot be established.
	 */
	xprt_init_majortimeo(task, req, to);
}
#endif

static void xprt_init(struct rpc_xprt *xprt, struct net *net)
{
	kref_init(&xprt->kref);

	spin_lock_init(&xprt->transport_lock);
	spin_lock_init(&xprt->reserve_lock);
	spin_lock_init(&xprt->queue_lock);

	INIT_LIST_HEAD(&xprt->free);
	xprt->recv_queue = RB_ROOT;
	INIT_LIST_HEAD(&xprt->xmit_queue);
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
	spin_lock_init(&xprt->bc_pa_lock);
	INIT_LIST_HEAD(&xprt->bc_pa_list);
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
	INIT_LIST_HEAD(&xprt->xprt_switch);

	xprt->last_used = jiffies;
	xprt->cwnd = RPC_INITCWND;
	xprt->bind_index = 0;

	rpc_init_wait_queue(&xprt->binding, "xprt_binding");
	rpc_init_wait_queue(&xprt->pending, "xprt_pending");
	rpc_init_wait_queue(&xprt->sending, "xprt_sending");
	rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog");

	xprt_init_xid(xprt);

	xprt->xprt_net = get_net_track(net, &xprt->ns_tracker, GFP_KERNEL);
}

/**
 * xprt_create_transport - create an RPC transport
 * @args: rpc transport creation arguments
 *
 */
struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
{
	struct rpc_xprt	*xprt;
	const struct xprt_class *t;

	t = xprt_class_find_by_ident(args->ident);
	if (!t) {
		dprintk("RPC: transport (%d) not supported\n", args->ident);
		return ERR_PTR(-EIO);
	}

	xprt = t->setup(args);
	xprt_class_release(t);

	if (IS_ERR(xprt))
		goto out;
	if (args->flags & XPRT_CREATE_NO_IDLE_TIMEOUT)
		xprt->idle_timeout = 0;
	INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
	if (xprt_has_timer(xprt))
		timer_setup(&xprt->timer, xprt_init_autodisconnect, 0);
	else
		timer_setup(&xprt->timer, NULL, 0);

	if (strlen(args->servername) > RPC_MAXNETNAMELEN) {
		xprt_destroy(xprt);
		return ERR_PTR(-EINVAL);
	}
	xprt->servername = kstrdup(args->servername, GFP_KERNEL);
	if (xprt->servername == NULL) {
		xprt_destroy(xprt);
		return ERR_PTR(-ENOMEM);
	}

	rpc_xprt_debugfs_register(xprt);

	trace_xprt_create(xprt);
out:
	return xprt;
}

static void xprt_destroy_cb(struct work_struct *work)
{
	struct rpc_xprt *xprt =
		container_of(work, struct rpc_xprt, task_cleanup);

	trace_xprt_destroy(xprt);

	rpc_xprt_debugfs_unregister(xprt);
	rpc_destroy_wait_queue(&xprt->binding);
	rpc_destroy_wait_queue(&xprt->pending);
	rpc_destroy_wait_queue(&xprt->sending);
	rpc_destroy_wait_queue(&xprt->backlog);
	kfree(xprt->servername);
	/*
	 * Destroy any existing back channel
	 */
	xprt_destroy_backchannel(xprt, UINT_MAX);

	/*
	 * Tear down transport state and free the rpc_xprt
	 */
	xprt->ops->destroy(xprt);
}

/**
 * xprt_destroy - destroy an RPC transport, killing off all requests.
 * @xprt: transport to destroy
 *
 */
static void xprt_destroy(struct rpc_xprt *xprt)
{
	/*
	 * Exclude transport connect/disconnect handlers and autoclose
	 */
	wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_UNINTERRUPTIBLE);

	/*
	 * xprt_schedule_autodisconnect() can run after XPRT_LOCKED
	 * is cleared.  We use ->transport_lock to ensure the mod_timer()
	 * can only run *before* del_time_sync(), never after.
	 */
	spin_lock(&xprt->transport_lock);
	del_timer_sync(&xprt->timer);
	spin_unlock(&xprt->transport_lock);

	/*
	 * Destroy sockets etc from the system workqueue so they can
	 * safely flush receive work running on rpciod.
	 */
	INIT_WORK(&xprt->task_cleanup, xprt_destroy_cb);
	schedule_work(&xprt->task_cleanup);
}

static void xprt_destroy_kref(struct kref *kref)
{
	xprt_destroy(container_of(kref, struct rpc_xprt, kref));
}

/**
 * xprt_get - return a reference to an RPC transport.
 * @xprt: pointer to the transport
 *
 */
struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
{
	if (xprt != NULL && kref_get_unless_zero(&xprt->kref))
		return xprt;
	return NULL;
}
EXPORT_SYMBOL_GPL(xprt_get);

/**
 * xprt_put - release a reference to an RPC transport.
 * @xprt: pointer to the transport
 *
 */
void xprt_put(struct rpc_xprt *xprt)
{
	if (xprt != NULL)
		kref_put(&xprt->kref, xprt_destroy_kref);
}
EXPORT_SYMBOL_GPL(xprt_put);

void xprt_set_offline_locked(struct rpc_xprt *xprt, struct rpc_xprt_switch *xps)
{
	if (!test_and_set_bit(XPRT_OFFLINE, &xprt->state)) {
		spin_lock(&xps->xps_lock);
		xps->xps_nactive--;
		spin_unlock(&xps->xps_lock);
	}
}

void xprt_set_online_locked(struct rpc_xprt *xprt, struct rpc_xprt_switch *xps)
{
	if (test_and_clear_bit(XPRT_OFFLINE, &xprt->state)) {
		spin_lock(&xps->xps_lock);
		xps->xps_nactive++;
		spin_unlock(&xps->xps_lock);
	}
}

void xprt_delete_locked(struct rpc_xprt *xprt, struct rpc_xprt_switch *xps)
{
	if (test_and_set_bit(XPRT_REMOVE, &xprt->state))
		return;

	xprt_force_disconnect(xprt);
	if (!test_bit(XPRT_CONNECTED, &xprt->state))
		return;

	if (!xprt->sending.qlen && !xprt->pending.qlen &&
	    !xprt->backlog.qlen && !atomic_long_read(&xprt->queuelen))
		rpc_xprt_switch_remove_xprt(xps, xprt, true);
}
