net/sunrpc/clnt.c
Source file repositories/reference/linux-study-clean/net/sunrpc/clnt.c
File Facts
- System
- Linux kernel
- Corpus path
net/sunrpc/clnt.c- Extension
.c- Size
- 82860 bytes
- Lines
- 3426
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/types.hlinux/kallsyms.hlinux/mm.hlinux/namei.hlinux/mount.hlinux/slab.hlinux/rcupdate.hlinux/utsname.hlinux/workqueue.hlinux/in.hlinux/in6.hlinux/un.hlinux/sunrpc/clnt.hlinux/sunrpc/addr.hlinux/sunrpc/rpc_pipe_fs.hlinux/sunrpc/metrics.hlinux/sunrpc/bc_xprt.htrace/events/sunrpc.hsunrpc.hsysfs.hnetns.h
Detected Declarations
struct rpc_cb_add_xprt_calldatastruct connect_timeout_datafunction rpc_register_clientfunction rpc_unregister_clientfunction __rpc_clnt_remove_pipedirfunction rpc_clnt_remove_pipedirfunction rpc_setup_pipedir_sbfunction rpc_setup_pipedirfunction rpc_clnt_skip_eventfunction __rpc_clnt_handle_eventfunction __rpc_pipefs_eventfunction rpc_pipefs_eventfunction rpc_clients_notifier_registerfunction rpc_clients_notifier_unregisterfunction rpc_clnt_set_nodenamefunction rpc_client_registerfunction rpc_cleanup_clidsfunction rpc_alloc_clidfunction rpc_free_clidfunction rpc_new_clientfunction rpc_clone_client_set_authfunction rpc_switch_client_transportfunction _rpc_clnt_xprt_iter_initfunction rpc_clnt_xprt_iter_initfunction rpc_clnt_xprt_iter_offline_initfunction fnfunction rpc_killall_tasksfunction rpc_cancel_tasksfunction rpc_clnt_disconnect_xprtfunction rpc_clnt_disconnectfunction rpc_shutdown_clientfunction rpc_free_client_workfunction rpc_free_clientfunction rpc_free_authfunction rpc_release_clientfunction rpc_task_get_xprtfunction rpc_task_release_xprtfunction rpc_task_release_transportfunction rpc_task_release_clientfunction rpc_task_get_first_xprtfunction rpc_task_get_next_xprtfunction rpc_task_set_transportfunction rpc_task_set_clientfunction rpc_task_set_rpc_messagefunction rpc_default_callbackfunction rpc_call_syncfunction rpc_call_asyncfunction rpc_prepare_reply_pages
Annotated Snippet
struct rpc_cb_add_xprt_calldata {
struct rpc_xprt_switch *xps;
struct rpc_xprt *xprt;
};
static void rpc_cb_add_xprt_done(struct rpc_task *task, void *calldata)
{
struct rpc_cb_add_xprt_calldata *data = calldata;
if (task->tk_status == 0)
rpc_xprt_switch_add_xprt(data->xps, data->xprt);
}
static void rpc_cb_add_xprt_release(void *calldata)
{
struct rpc_cb_add_xprt_calldata *data = calldata;
xprt_put(data->xprt);
xprt_switch_put(data->xps);
kfree(data);
}
static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = {
.rpc_call_prepare = rpc_null_call_prepare,
.rpc_call_done = rpc_cb_add_xprt_done,
.rpc_release = rpc_cb_add_xprt_release,
};
/**
* rpc_clnt_test_and_add_xprt - Test and add a new transport to a rpc_clnt
* @clnt: pointer to struct rpc_clnt
* @xps: pointer to struct rpc_xprt_switch,
* @xprt: pointer struct rpc_xprt
* @in_max_connect: pointer to the max_connect value for the passed in xprt transport
*/
int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
struct rpc_xprt_switch *xps, struct rpc_xprt *xprt,
void *in_max_connect)
{
struct rpc_cb_add_xprt_calldata *data;
struct rpc_task *task;
int max_connect = clnt->cl_max_connect;
if (in_max_connect)
max_connect = *(int *)in_max_connect;
if (xps->xps_nunique_destaddr_xprts + 1 > max_connect) {
rcu_read_lock();
pr_warn("SUNRPC: reached max allowed number (%d) did not add "
"transport to server: %s\n", max_connect,
rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR));
rcu_read_unlock();
return -EINVAL;
}
data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
data->xps = xprt_switch_get(xps);
data->xprt = xprt_get(xprt);
if (rpc_xprt_switch_has_addr(data->xps, (struct sockaddr *)&xprt->addr)) {
rpc_cb_add_xprt_release(data);
goto success;
}
task = rpc_call_null_helper(clnt, xprt, NULL, RPC_TASK_ASYNC,
&rpc_cb_add_xprt_call_ops, data);
if (IS_ERR(task))
return PTR_ERR(task);
data->xps->xps_nunique_destaddr_xprts++;
rpc_put_task(task);
success:
return 1;
}
EXPORT_SYMBOL_GPL(rpc_clnt_test_and_add_xprt);
static int rpc_clnt_add_xprt_helper(struct rpc_clnt *clnt,
struct rpc_xprt *xprt,
struct rpc_add_xprt_test *data)
{
struct rpc_task *task;
int status = -EADDRINUSE;
/* Test the connection */
task = rpc_call_null_helper(clnt, xprt, NULL, 0, NULL, NULL);
if (IS_ERR(task))
return PTR_ERR(task);
status = task->tk_status;
rpc_put_task(task);
Annotation
- Immediate include surface: `linux/module.h`, `linux/types.h`, `linux/kallsyms.h`, `linux/mm.h`, `linux/namei.h`, `linux/mount.h`, `linux/slab.h`, `linux/rcupdate.h`.
- Detected declarations: `struct rpc_cb_add_xprt_calldata`, `struct connect_timeout_data`, `function rpc_register_client`, `function rpc_unregister_client`, `function __rpc_clnt_remove_pipedir`, `function rpc_clnt_remove_pipedir`, `function rpc_setup_pipedir_sb`, `function rpc_setup_pipedir`, `function rpc_clnt_skip_event`, `function __rpc_clnt_handle_event`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.