// SPDX-License-Identifier: GPL-2.0-only /****************************************************************************** (c) 2007 Network Appliance, Inc. All Rights Reserved. (c) 2009 NetApp. All Rights Reserved. ******************************************************************************/ #include <linux/tcp.h> #include <linux/slab.h> #include <linux/sunrpc/xprt.h> #include <linux/export.h> #include <linux/sunrpc/bc_xprt.h> #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) #define RPCDBG_FACILITY … #endif #define BC_MAX_SLOTS … unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt) { … } /* * Helper routines that track the number of preallocation elements * on the transport. */ static inline int xprt_need_to_requeue(struct rpc_xprt *xprt) { … } /* * Free the preallocated rpc_rqst structure and the memory * buffers hanging off of it. */ static void xprt_free_allocation(struct rpc_rqst *req) { … } static void xprt_bc_reinit_xdr_buf(struct xdr_buf *buf) { … } static int xprt_alloc_xdr_buf(struct xdr_buf *buf, gfp_t gfp_flags) { … } static struct rpc_rqst *xprt_alloc_bc_req(struct rpc_xprt *xprt) { … } /* * Preallocate up to min_reqs structures and related buffers for use * by the backchannel. This function can be called multiple times * when creating new sessions that use the same rpc_xprt. The * preallocated buffers are added to the pool of resources used by * the rpc_xprt. Any one of these resources may be used by an * incoming callback request. It's up to the higher levels in the * stack to enforce that the maximum number of session slots is not * being exceeded. * * Some callback arguments can be large. For example, a pNFS server * using multiple deviceids. The list can be unbound, but the client * has the ability to tell the server the maximum size of the callback * requests. Each deviceID is 16 bytes, so allocate one page * for the arguments to have enough room to receive a number of these * deviceIDs. The NFS client indicates to the pNFS server that its * callback requests can be up to 4096 bytes in size. */ int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) { … } EXPORT_SYMBOL_GPL(…); int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs) { … } /** * xprt_destroy_backchannel - Destroys the backchannel preallocated structures. * @xprt: the transport holding the preallocated strucures * @max_reqs: the maximum number of preallocated structures to destroy * * Since these structures may have been allocated by multiple calls * to xprt_setup_backchannel, we only destroy up to the maximum number * of reqs specified by the caller. */ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs) { … } EXPORT_SYMBOL_GPL(…); void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs) { … } static struct rpc_rqst *xprt_get_bc_request(struct rpc_xprt *xprt, __be32 xid, struct rpc_rqst *new) { … } /* * Return the preallocated rpc_rqst structure and XDR buffers * associated with this rpc_task. */ void xprt_free_bc_request(struct rpc_rqst *req) { … } void xprt_free_bc_rqst(struct rpc_rqst *req) { … } /* * One or more rpc_rqst structure have been preallocated during the * backchannel setup. Buffer space for the send and private XDR buffers * has been preallocated as well. Use xprt_alloc_bc_request to allocate * to this request. Use xprt_free_bc_request to return it. * * We know that we're called in soft interrupt context, grab the spin_lock * since there is no need to grab the bottom half spin_lock. * * Return an available rpc_rqst, otherwise NULL if non are available. */ struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid) { … } /* * Add callback request to callback list. Wake a thread * on the first pool (usually the only pool) to handle it. */ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) { … }