diff options
-rw-r--r-- | net/sunrpc/pmap_clnt.c | 70 |
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 | */ |
83 | void | 89 | void rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt) |
84 | rpc_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 |
147 | int | 152 | /** |
148 | rpc_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 | */ | ||
161 | int 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 | ||
185 | static void | 198 | /* |
186 | pmap_getport_done(struct rpc_task *child, void *data) | 199 | * Portmapper child task invokes this callback via tk_exit. |
200 | */ | ||
201 | static 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 | */ |
218 | int | 239 | int rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) |
219 | rpc_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 | ||
262 | static struct rpc_clnt * | 282 | static struct rpc_clnt *pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged) |
263 | pmap_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 | */ |
291 | static int | 308 | static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map) |
292 | xdr_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 | ||
305 | static int | 321 | static int xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp) |
306 | xdr_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 | ||
312 | static int | 327 | static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp) |
313 | xdr_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; |