#include <linux/module.h>
#include <linux/types.h>
#include <linux/kallsyms.h>
#include <linux/mm.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <linux/utsname.h>
#include <linux/workqueue.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/un.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/addr.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
#include <linux/sunrpc/metrics.h>
#include <linux/sunrpc/bc_xprt.h>
#include <trace/events/sunrpc.h>
#include "sunrpc.h"
#include "sysfs.h"
#include "netns.h"
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
#define RPCDBG_FACILITY …
#endif
static DECLARE_WAIT_QUEUE_HEAD(destroy_wait);
static void call_start(struct rpc_task *task);
static void call_reserve(struct rpc_task *task);
static void call_reserveresult(struct rpc_task *task);
static void call_allocate(struct rpc_task *task);
static void call_encode(struct rpc_task *task);
static void call_decode(struct rpc_task *task);
static void call_bind(struct rpc_task *task);
static void call_bind_status(struct rpc_task *task);
static void call_transmit(struct rpc_task *task);
static void call_status(struct rpc_task *task);
static void call_transmit_status(struct rpc_task *task);
static void call_refresh(struct rpc_task *task);
static void call_refreshresult(struct rpc_task *task);
static void call_connect(struct rpc_task *task);
static void call_connect_status(struct rpc_task *task);
static int rpc_encode_header(struct rpc_task *task,
struct xdr_stream *xdr);
static int rpc_decode_header(struct rpc_task *task,
struct xdr_stream *xdr);
static int rpc_ping(struct rpc_clnt *clnt);
static int rpc_ping_noreply(struct rpc_clnt *clnt);
static void rpc_check_timeout(struct rpc_task *task);
static void rpc_register_client(struct rpc_clnt *clnt)
{ … }
static void rpc_unregister_client(struct rpc_clnt *clnt)
{ … }
static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
{ … }
static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
{ … }
static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
struct rpc_clnt *clnt)
{ … }
static int
rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt)
{ … }
static int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
{ … }
static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event,
struct super_block *sb)
{ … }
static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
struct super_block *sb)
{ … }
static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
{ … }
static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
void *ptr)
{ … }
static struct notifier_block rpc_clients_block = …;
int rpc_clients_notifier_register(void)
{ … }
void rpc_clients_notifier_unregister(void)
{ … }
static struct rpc_xprt *rpc_clnt_set_transport(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
const struct rpc_timeout *timeout)
{ … }
static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
{ … }
static int rpc_client_register(struct rpc_clnt *clnt,
rpc_authflavor_t pseudoflavor,
const char *client_name)
{ … }
static DEFINE_IDA(rpc_clids);
void rpc_cleanup_clids(void)
{ … }
static int rpc_alloc_clid(struct rpc_clnt *clnt)
{ … }
static void rpc_free_clid(struct rpc_clnt *clnt)
{ … }
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
struct rpc_xprt_switch *xps,
struct rpc_xprt *xprt,
struct rpc_clnt *parent)
{ … }
static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
struct rpc_xprt *xprt)
{ … }
struct rpc_clnt *rpc_create(struct rpc_create_args *args)
{ … }
EXPORT_SYMBOL_GPL(…);
static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
struct rpc_clnt *clnt)
{ … }
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
struct rpc_clnt *
rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
{ … }
EXPORT_SYMBOL_GPL(…);
int rpc_switch_client_transport(struct rpc_clnt *clnt,
struct xprt_create *args,
const struct rpc_timeout *timeout)
{ … }
EXPORT_SYMBOL_GPL(…);
static struct rpc_xprt_switch *rpc_clnt_xprt_switch_get(struct rpc_clnt *clnt)
{ … }
static
int _rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi,
void func(struct rpc_xprt_iter *xpi, struct rpc_xprt_switch *xps))
{ … }
static
int rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi)
{ … }
static
int rpc_clnt_xprt_iter_offline_init(struct rpc_clnt *clnt,
struct rpc_xprt_iter *xpi)
{ … }
int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
void *data)
{ … }
EXPORT_SYMBOL_GPL(…);
void rpc_killall_tasks(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
unsigned long rpc_cancel_tasks(struct rpc_clnt *clnt, int error,
bool (*fnmatch)(const struct rpc_task *,
const void *),
const void *data)
{ … }
EXPORT_SYMBOL_GPL(…);
static int rpc_clnt_disconnect_xprt(struct rpc_clnt *clnt,
struct rpc_xprt *xprt, void *dummy)
{ … }
void rpc_clnt_disconnect(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
void rpc_shutdown_client(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
static void rpc_free_client_work(struct work_struct *work)
{ … }
static struct rpc_clnt *
rpc_free_client(struct rpc_clnt *clnt)
{ … }
static struct rpc_clnt *
rpc_free_auth(struct rpc_clnt *clnt)
{ … }
void
rpc_release_client(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
const struct rpc_program *program,
u32 vers)
{ … }
EXPORT_SYMBOL_GPL(…);
struct rpc_xprt *
rpc_task_get_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
{ … }
static void
rpc_task_release_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
{ … }
void rpc_task_release_transport(struct rpc_task *task)
{ … }
EXPORT_SYMBOL_GPL(…);
void rpc_task_release_client(struct rpc_task *task)
{ … }
static struct rpc_xprt *
rpc_task_get_first_xprt(struct rpc_clnt *clnt)
{ … }
static struct rpc_xprt *
rpc_task_get_next_xprt(struct rpc_clnt *clnt)
{ … }
static
void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
{ … }
static
void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
{ … }
static void
rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
{ … }
static void
rpc_default_callback(struct rpc_task *task, void *data)
{ … }
static const struct rpc_call_ops rpc_default_ops = …;
struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
{ … }
EXPORT_SYMBOL_GPL(…);
int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags)
{ … }
EXPORT_SYMBOL_GPL(…);
int
rpc_call_async(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags,
const struct rpc_call_ops *tk_ops, void *data)
{ … }
EXPORT_SYMBOL_GPL(…);
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
static void call_bc_encode(struct rpc_task *task);
struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
struct rpc_timeout *timeout)
{ … }
#endif
void rpc_prepare_reply_pages(struct rpc_rqst *req, struct page **pages,
unsigned int base, unsigned int len,
unsigned int hdrsize)
{ … }
EXPORT_SYMBOL_GPL(…);
void
rpc_call_start(struct rpc_task *task)
{ … }
EXPORT_SYMBOL_GPL(…);
size_t rpc_peeraddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t bufsize)
{ … }
EXPORT_SYMBOL_GPL(…);
const char *rpc_peeraddr2str(struct rpc_clnt *clnt,
enum rpc_display_format_t format)
{ … }
EXPORT_SYMBOL_GPL(…);
static const struct sockaddr_in rpc_inaddr_loopback = …;
static const struct sockaddr_in6 rpc_in6addr_loopback = …;
static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen,
struct sockaddr *buf)
{ … }
static int rpc_anyaddr(int family, struct sockaddr *buf, size_t buflen)
{ … }
int rpc_localaddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t buflen)
{ … }
EXPORT_SYMBOL_GPL(…);
void
rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize)
{ … }
EXPORT_SYMBOL_GPL(…);
struct net *rpc_net_ns(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
size_t rpc_max_payload(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
size_t rpc_max_bc_payload(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
unsigned int rpc_num_bc_slots(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
void rpc_force_rebind(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
static int
__rpc_restart_call(struct rpc_task *task, void (*action)(struct rpc_task *))
{ … }
int
rpc_restart_call(struct rpc_task *task)
{ … }
EXPORT_SYMBOL_GPL(…);
int
rpc_restart_call_prepare(struct rpc_task *task)
{ … }
EXPORT_SYMBOL_GPL(…);
const char
*rpc_proc_name(const struct rpc_task *task)
{ … }
static void
__rpc_call_rpcerror(struct rpc_task *task, int tk_status, int rpc_status)
{ … }
static void
rpc_call_rpcerror(struct rpc_task *task, int status)
{ … }
static void
call_start(struct rpc_task *task)
{ … }
static void
call_reserve(struct rpc_task *task)
{ … }
static void call_retry_reserve(struct rpc_task *task);
static void
call_reserveresult(struct rpc_task *task)
{ … }
static void
call_retry_reserve(struct rpc_task *task)
{ … }
static void
call_refresh(struct rpc_task *task)
{ … }
static void
call_refreshresult(struct rpc_task *task)
{ … }
static void
call_allocate(struct rpc_task *task)
{ … }
static int
rpc_task_need_encode(struct rpc_task *task)
{ … }
static void
rpc_xdr_encode(struct rpc_task *task)
{ … }
static void
call_encode(struct rpc_task *task)
{ … }
static bool
rpc_task_transmitted(struct rpc_task *task)
{ … }
static void
rpc_task_handle_transmitted(struct rpc_task *task)
{ … }
static void
call_bind(struct rpc_task *task)
{ … }
static void
call_bind_status(struct rpc_task *task)
{ … }
static void
call_connect(struct rpc_task *task)
{ … }
static void
call_connect_status(struct rpc_task *task)
{ … }
static void
call_transmit(struct rpc_task *task)
{ … }
static void
call_transmit_status(struct rpc_task *task)
{ … }
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
static void call_bc_transmit(struct rpc_task *task);
static void call_bc_transmit_status(struct rpc_task *task);
static void
call_bc_encode(struct rpc_task *task)
{ … }
static void
call_bc_transmit(struct rpc_task *task)
{ … }
static void
call_bc_transmit_status(struct rpc_task *task)
{ … }
#endif
static void
call_status(struct rpc_task *task)
{ … }
static bool
rpc_check_connected(const struct rpc_rqst *req)
{ … }
static void
rpc_check_timeout(struct rpc_task *task)
{ … }
static void
call_decode(struct rpc_task *task)
{ … }
static int
rpc_encode_header(struct rpc_task *task, struct xdr_stream *xdr)
{ … }
static noinline int
rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
{ … }
static void rpcproc_encode_null(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
const void *obj)
{ … }
static int rpcproc_decode_null(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
void *obj)
{ … }
static const struct rpc_procinfo rpcproc_null = …;
static const struct rpc_procinfo rpcproc_null_noreply = …;
static void
rpc_null_call_prepare(struct rpc_task *task, void *data)
{ … }
static const struct rpc_call_ops rpc_null_ops = …;
static
struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt,
struct rpc_xprt *xprt, struct rpc_cred *cred, int flags,
const struct rpc_call_ops *ops, void *data)
{ … }
struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags)
{ … }
EXPORT_SYMBOL_GPL(…);
static int rpc_ping(struct rpc_clnt *clnt)
{ … }
static int rpc_ping_noreply(struct rpc_clnt *clnt)
{ … }
struct rpc_cb_add_xprt_calldata { … };
static void rpc_cb_add_xprt_done(struct rpc_task *task, void *calldata)
{ … }
static void rpc_cb_add_xprt_release(void *calldata)
{ … }
static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = …;
int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
struct rpc_xprt_switch *xps, struct rpc_xprt *xprt,
void *in_max_connect)
{ … }
EXPORT_SYMBOL_GPL(…);
static int rpc_clnt_add_xprt_helper(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
struct rpc_add_xprt_test *data)
{ … }
int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt,
struct rpc_xprt_switch *xps,
struct rpc_xprt *xprt,
void *data)
{ … }
EXPORT_SYMBOL_GPL(…);
int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
struct xprt_create *xprtargs,
int (*setup)(struct rpc_clnt *,
struct rpc_xprt_switch *,
struct rpc_xprt *,
void *),
void *data)
{ … }
EXPORT_SYMBOL_GPL(…);
static int rpc_xprt_probe_trunked(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
struct rpc_add_xprt_test *data)
{ … }
void rpc_clnt_probe_trunked_xprts(struct rpc_clnt *clnt,
struct rpc_add_xprt_test *data)
{ … }
EXPORT_SYMBOL_GPL(…);
static int rpc_xprt_offline(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
void *data)
{ … }
void rpc_clnt_manage_trunked_xprts(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
struct connect_timeout_data { … };
static int
rpc_xprt_set_connect_timeout(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
void *data)
{ … }
void
rpc_set_connect_timeout(struct rpc_clnt *clnt,
unsigned long connect_timeout,
unsigned long reconnect_timeout)
{ … }
EXPORT_SYMBOL_GPL(…);
void rpc_clnt_xprt_set_online(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
{ … }
void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
{ … }
EXPORT_SYMBOL_GPL(…);
void rpc_clnt_xprt_switch_remove_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
{ … }
EXPORT_SYMBOL_GPL(…);
bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
const struct sockaddr *sap)
{ … }
EXPORT_SYMBOL_GPL(…);
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
static void rpc_show_header(void)
{ … }
static void rpc_show_task(const struct rpc_clnt *clnt,
const struct rpc_task *task)
{ … }
void rpc_show_tasks(struct net *net)
{ … }
#endif
#if IS_ENABLED(CONFIG_SUNRPC_SWAP)
static int
rpc_clnt_swap_activate_callback(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
void *dummy)
{ … }
int
rpc_clnt_swap_activate(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
static int
rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
void *dummy)
{ … }
void
rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
{ … }
EXPORT_SYMBOL_GPL(…);
#endif