aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/pmap_clnt.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index 59d542436ca9..0efcbf1302a2 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -1,7 +1,9 @@
1/* 1/*
2 * linux/net/sunrpc/pmap.c 2 * linux/net/sunrpc/pmap_clnt.c
3 * 3 *
4 * Portmapper client. 4 * In-kernel RPC portmapper client.
5 *
6 * Portmapper supports version 2 of the rpcbind protocol (RFC 1833).
5 * 7 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 8 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */ 9 */
@@ -76,12 +78,15 @@ static inline void pmap_wake_portmap_waiters(struct rpc_xprt *xprt)
76 rpc_wake_up(&xprt->binding); 78 rpc_wake_up(&xprt->binding);
77} 79}
78 80
79/* 81/**
80 * Obtain the port for a given RPC service on a given host. This one can 82 * rpc_getport - obtain the port for a given RPC service on a given host
81 * be called for an ongoing RPC request. 83 * @task: task that is waiting for portmapper request
84 * @clnt: controlling rpc_clnt
85 *
86 * This one can be called for an ongoing RPC request, and can be used in
87 * an async (rpciod) context.
82 */ 88 */
83void 89void rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
84rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
85{ 90{
86 struct rpc_xprt *xprt = task->tk_xprt; 91 struct rpc_xprt *xprt = task->tk_xprt;
87 struct sockaddr_in *sap = &xprt->addr; 92 struct sockaddr_in *sap = &xprt->addr;
@@ -144,8 +149,16 @@ bailout_nofree:
144} 149}
145 150
146#ifdef CONFIG_ROOT_NFS 151#ifdef CONFIG_ROOT_NFS
147int 152/**
148rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot) 153 * rpc_getport_external - obtain the port for a given RPC service on a given host
154 * @sin: address of remote peer
155 * @prog: RPC program number to bind
156 * @vers: RPC version number to bind
157 * @prot: transport protocol to use to make this request
158 *
159 * This one is called from outside the RPC client in a synchronous task context.
160 */
161int rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
149{ 162{
150 struct portmap_args map = { 163 struct portmap_args map = {
151 .pm_prog = prog, 164 .pm_prog = prog,
@@ -162,7 +175,7 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
162 char hostname[32]; 175 char hostname[32];
163 int status; 176 int status;
164 177
165 dprintk("RPC: rpc_getport_external(%u.%u.%u.%u, %d, %d, %d)\n", 178 dprintk("RPC: rpc_getport_external(%u.%u.%u.%u, %u, %u, %d)\n",
166 NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); 179 NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
167 180
168 sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr)); 181 sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
@@ -182,8 +195,10 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
182} 195}
183#endif 196#endif
184 197
185static void 198/*
186pmap_getport_done(struct rpc_task *child, void *data) 199 * Portmapper child task invokes this callback via tk_exit.
200 */
201static void pmap_getport_done(struct rpc_task *child, void *data)
187{ 202{
188 struct portmap_args *map = data; 203 struct portmap_args *map = data;
189 struct rpc_task *task = map->pm_task; 204 struct rpc_task *task = map->pm_task;
@@ -211,12 +226,17 @@ pmap_getport_done(struct rpc_task *child, void *data)
211 pmap_wake_portmap_waiters(xprt); 226 pmap_wake_portmap_waiters(xprt);
212} 227}
213 228
214/* 229/**
215 * Set or unset a port registration with the local portmapper. 230 * rpc_register - set or unset a port registration with the local portmapper
231 * @prog: RPC program number to bind
232 * @vers: RPC version number to bind
233 * @prot: transport protocol to use to make this request
234 * @port: port value to register
235 * @okay: result code
236 *
216 * port == 0 means unregister, port != 0 means register. 237 * port == 0 means unregister, port != 0 means register.
217 */ 238 */
218int 239int rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
219rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
220{ 240{
221 struct sockaddr_in sin = { 241 struct sockaddr_in sin = {
222 .sin_family = AF_INET, 242 .sin_family = AF_INET,
@@ -236,7 +256,7 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
236 struct rpc_clnt *pmap_clnt; 256 struct rpc_clnt *pmap_clnt;
237 int error = 0; 257 int error = 0;
238 258
239 dprintk("RPC: registering (%d, %d, %d, %d) with portmapper.\n", 259 dprintk("RPC: registering (%u, %u, %d, %u) with portmapper.\n",
240 prog, vers, prot, port); 260 prog, vers, prot, port);
241 261
242 pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1); 262 pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1);
@@ -259,13 +279,11 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
259 return error; 279 return error;
260} 280}
261 281
262static struct rpc_clnt * 282static struct rpc_clnt *pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged)
263pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged)
264{ 283{
265 struct rpc_xprt *xprt; 284 struct rpc_xprt *xprt;
266 struct rpc_clnt *clnt; 285 struct rpc_clnt *clnt;
267 286
268 /* printk("pmap: create xprt\n"); */
269 xprt = xprt_create_proto(proto, srvaddr, NULL); 287 xprt = xprt_create_proto(proto, srvaddr, NULL);
270 if (IS_ERR(xprt)) 288 if (IS_ERR(xprt))
271 return (struct rpc_clnt *)xprt; 289 return (struct rpc_clnt *)xprt;
@@ -274,7 +292,6 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileg
274 if (!privileged) 292 if (!privileged)
275 xprt->resvport = 0; 293 xprt->resvport = 0;
276 294
277 /* printk("pmap: create clnt\n"); */
278 clnt = rpc_new_client(xprt, hostname, 295 clnt = rpc_new_client(xprt, hostname,
279 &pmap_program, RPC_PMAP_VERSION, 296 &pmap_program, RPC_PMAP_VERSION,
280 RPC_AUTH_UNIX); 297 RPC_AUTH_UNIX);
@@ -288,10 +305,9 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileg
288/* 305/*
289 * XDR encode/decode functions for PMAP 306 * XDR encode/decode functions for PMAP
290 */ 307 */
291static int 308static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
292xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
293{ 309{
294 dprintk("RPC: xdr_encode_mapping(%d, %d, %d, %d)\n", 310 dprintk("RPC: xdr_encode_mapping(%u, %u, %u, %u)\n",
295 map->pm_prog, map->pm_vers, map->pm_prot, map->pm_port); 311 map->pm_prog, map->pm_vers, map->pm_prot, map->pm_port);
296 *p++ = htonl(map->pm_prog); 312 *p++ = htonl(map->pm_prog);
297 *p++ = htonl(map->pm_vers); 313 *p++ = htonl(map->pm_vers);
@@ -302,15 +318,13 @@ xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
302 return 0; 318 return 0;
303} 319}
304 320
305static int 321static int xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp)
306xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp)
307{ 322{
308 *portp = (unsigned short) ntohl(*p++); 323 *portp = (unsigned short) ntohl(*p++);
309 return 0; 324 return 0;
310} 325}
311 326
312static int 327static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
313xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
314{ 328{
315 *boolp = (unsigned int) ntohl(*p++); 329 *boolp = (unsigned int) ntohl(*p++);
316 return 0; 330 return 0;