#include <linux/uio.h>
#include <linux/in.h>
#include <linux/sunrpc/clnt.h>
-#include <linux/sunrpc/xprt.h>
#include <linux/sunrpc/sched.h>
#ifdef RPC_DEBUG
u32 pm_vers;
u32 pm_prot;
unsigned short pm_port;
- struct rpc_task * pm_task;
+ struct rpc_xprt * pm_xprt;
};
static struct rpc_procinfo pmap_procedures[];
.rpc_release = pmap_map_release,
};
-static inline void pmap_wake_portmap_waiters(struct rpc_xprt *xprt)
+static inline void pmap_wake_portmap_waiters(struct rpc_xprt *xprt, int status)
{
xprt_clear_binding(xprt);
- rpc_wake_up(&xprt->binding);
+ rpc_wake_up_status(&xprt->binding, status);
}
/**
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_xprt *xprt = task->tk_xprt;
- struct sockaddr_in *sap = &xprt->addr;
+ struct sockaddr_in addr;
struct portmap_args *map;
struct rpc_clnt *pmap_clnt;
struct rpc_task *child;
+ int status;
dprintk("RPC: %4d rpc_getport(%s, %u, %u, %d)\n",
task->tk_pid, clnt->cl_server,
}
/* Someone else may have bound if we slept */
- if (xprt_bound(xprt)) {
- task->tk_status = 0;
+ status = 0;
+ if (xprt_bound(xprt))
goto bailout_nofree;
- }
+ status = -ENOMEM;
map = pmap_map_alloc();
- if (!map) {
- task->tk_status = -ENOMEM;
+ if (!map)
goto bailout_nofree;
- }
map->pm_prog = clnt->cl_prog;
map->pm_vers = clnt->cl_vers;
map->pm_prot = xprt->prot;
map->pm_port = 0;
- map->pm_task = task;
+ map->pm_xprt = xprt_get(xprt);
- pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot, 0);
- if (IS_ERR(pmap_clnt)) {
- task->tk_status = PTR_ERR(pmap_clnt);
+ rpc_peeraddr(clnt, (struct sockaddr *) &addr, sizeof(addr));
+ pmap_clnt = pmap_create(clnt->cl_server, &addr, map->pm_prot, 0);
+ status = PTR_ERR(pmap_clnt);
+ if (IS_ERR(pmap_clnt))
goto bailout;
- }
+ status = -EIO;
child = rpc_run_task(pmap_clnt, RPC_TASK_ASYNC, &pmap_getport_ops, map);
- if (IS_ERR(child)) {
- task->tk_status = -EIO;
+ if (IS_ERR(child))
goto bailout;
- }
rpc_release_task(child);
rpc_sleep_on(&xprt->binding, task, NULL, NULL);
bailout:
pmap_map_free(map);
+ xprt_put(xprt);
bailout_nofree:
- pmap_wake_portmap_waiters(xprt);
+ task->tk_status = status;
+ pmap_wake_portmap_waiters(xprt, status);
}
#ifdef CONFIG_ROOT_NFS
static void pmap_getport_done(struct rpc_task *child, void *data)
{
struct portmap_args *map = data;
- struct rpc_task *task = map->pm_task;
- struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_xprt *xprt = map->pm_xprt;
int status = child->tk_status;
if (status < 0) {
/* Portmapper not available */
xprt->ops->set_port(xprt, 0);
- task->tk_status = status;
} else if (map->pm_port == 0) {
/* Requested RPC service wasn't registered */
xprt->ops->set_port(xprt, 0);
- task->tk_status = -EACCES;
+ status = -EACCES;
} else {
/* Succeeded */
xprt->ops->set_port(xprt, map->pm_port);
xprt_set_bound(xprt);
- task->tk_status = 0;
+ status = 0;
}
dprintk("RPC: %4d pmap_getport_done(status %d, port %u)\n",
- child->tk_pid, child->tk_status, map->pm_port);
+ child->tk_pid, status, map->pm_port);
- pmap_wake_portmap_waiters(xprt);
+ pmap_wake_portmap_waiters(xprt, status);
+ xprt_put(xprt);
}
/**
static struct rpc_clnt *pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged)
{
- struct rpc_xprt *xprt;
- struct rpc_clnt *clnt;
-
- xprt = xprt_create_proto(proto, srvaddr, NULL);
- if (IS_ERR(xprt))
- return (struct rpc_clnt *)xprt;
- xprt->ops->set_port(xprt, RPC_PMAP_PORT);
- xprt_set_bound(xprt);
+ struct rpc_create_args args = {
+ .protocol = proto,
+ .address = (struct sockaddr *)srvaddr,
+ .addrsize = sizeof(*srvaddr),
+ .servername = hostname,
+ .program = &pmap_program,
+ .version = RPC_PMAP_VERSION,
+ .authflavor = RPC_AUTH_UNIX,
+ .flags = (RPC_CLNT_CREATE_ONESHOT |
+ RPC_CLNT_CREATE_NOPING),
+ };
+
+ srvaddr->sin_port = htons(RPC_PMAP_PORT);
if (!privileged)
- xprt->resvport = 0;
-
- clnt = rpc_new_client(xprt, hostname,
- &pmap_program, RPC_PMAP_VERSION,
- RPC_AUTH_UNIX);
- if (!IS_ERR(clnt)) {
- clnt->cl_softrtry = 1;
- clnt->cl_oneshot = 1;
- }
- return clnt;
+ args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
+ return rpc_create(&args);
}
/*
* XDR encode/decode functions for PMAP
*/
-static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
+static int xdr_encode_mapping(struct rpc_rqst *req, __be32 *p, struct portmap_args *map)
{
dprintk("RPC: xdr_encode_mapping(%u, %u, %u, %u)\n",
map->pm_prog, map->pm_vers, map->pm_prot, map->pm_port);
return 0;
}
-static int xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp)
+static int xdr_decode_port(struct rpc_rqst *req, __be32 *p, unsigned short *portp)
{
*portp = (unsigned short) ntohl(*p++);
return 0;
}
-static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
+static int xdr_decode_bool(struct rpc_rqst *req, __be32 *p, unsigned int *boolp)
{
*boolp = (unsigned int) ntohl(*p++);
return 0;