net/sunrpc/rpcb_clnt.c

Source file repositories/reference/linux-study-clean/net/sunrpc/rpcb_clnt.c

File Facts

System
Linux kernel
Corpus path
net/sunrpc/rpcb_clnt.c
Extension
.c
Size
28939 bytes
Lines
1123
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rpcbind_args {
	struct rpc_xprt *	r_xprt;

	u32			r_prog;
	u32			r_vers;
	u32			r_prot;
	unsigned short		r_port;
	const char *		r_netid;
	const char *		r_addr;
	const char *		r_owner;

	int			r_status;
};

static const struct rpc_procinfo rpcb_procedures2[];
static const struct rpc_procinfo rpcb_procedures3[];
static const struct rpc_procinfo rpcb_procedures4[];

struct rpcb_info {
	u32			rpc_vers;
	const struct rpc_procinfo *rpc_proc;
};

static const struct rpcb_info rpcb_next_version[];
static const struct rpcb_info rpcb_next_version6[];

static const struct rpc_call_ops rpcb_getport_ops = {
	.rpc_call_done		= rpcb_getport_done,
	.rpc_release		= rpcb_map_release,
};

static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
{
	xprt_clear_binding(xprt);
	rpc_wake_up_status(&xprt->binding, status);
}

static void rpcb_map_release(void *data)
{
	struct rpcbind_args *map = data;

	rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
	xprt_put(map->r_xprt);
	kfree(map->r_addr);
	kfree(map);
}

static int rpcb_get_local(struct net *net)
{
	int cnt;
	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);

	spin_lock(&sn->rpcb_clnt_lock);
	if (sn->rpcb_users)
		sn->rpcb_users++;
	cnt = sn->rpcb_users;
	spin_unlock(&sn->rpcb_clnt_lock);

	return cnt;
}

void rpcb_put_local(struct net *net)
{
	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
	struct rpc_clnt *clnt = sn->rpcb_local_clnt;
	struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
	int shutdown = 0;

	spin_lock(&sn->rpcb_clnt_lock);
	if (sn->rpcb_users) {
		if (--sn->rpcb_users == 0) {
			sn->rpcb_local_clnt = NULL;
			sn->rpcb_local_clnt4 = NULL;
		}
		shutdown = !sn->rpcb_users;
	}
	spin_unlock(&sn->rpcb_clnt_lock);

	if (shutdown) {
		/*
		 * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
		 */
		if (clnt4)
			rpc_shutdown_client(clnt4);
		if (clnt)
			rpc_shutdown_client(clnt);
	}
}

static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,

Annotation

Implementation Notes