Commit 72cffe4f authored by Trond Myklebust's avatar Trond Myklebust

RPC,NFSv2/v3/v4: Ensure that xprt_create_proto() and rpc_create_client() return

     full error codes. Should allow the "mount" program to print more useful error
     diagnostics.
parent 0e459649
......@@ -188,14 +188,14 @@ nlm_bind_host(struct nlm_host *host)
}
} else {
xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL);
if (xprt == NULL)
if (IS_ERR(xprt))
goto forgetit;
xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
clnt = rpc_create_client(xprt, host->h_name, &nlm_program,
host->h_version, host->h_authflavor);
if (clnt == NULL) {
if (IS_ERR(clnt)) {
xprt_destroy(xprt);
goto forgetit;
}
......
......@@ -36,10 +36,11 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
int status;
struct nsm_args args;
status = -EACCES;
clnt = nsm_create();
if (!clnt)
if (IS_ERR(clnt)) {
status = PTR_ERR(clnt);
goto out;
}
args.addr = host->h_addr.sin_addr.s_addr;
args.proto= (host->h_proto<<1) | host->h_server;
......@@ -104,7 +105,7 @@ static struct rpc_clnt *
nsm_create(void)
{
struct rpc_xprt *xprt;
struct rpc_clnt *clnt = NULL;
struct rpc_clnt *clnt;
struct sockaddr_in sin;
sin.sin_family = AF_INET;
......@@ -112,24 +113,23 @@ nsm_create(void)
sin.sin_port = 0;
xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL);
if (!xprt)
goto out;
if (IS_ERR(xprt))
return (struct rpc_clnt *)xprt;
clnt = rpc_create_client(xprt, "localhost",
&nsm_program, SM_VERSION,
RPC_AUTH_NULL);
if (!clnt)
if (IS_ERR(clnt))
goto out_destroy;
clnt->cl_softrtry = 1;
clnt->cl_chatty = 1;
clnt->cl_oneshot = 1;
xprt->resvport = 1; /* NSM requires a reserved port */
out:
return clnt;
out_destroy:
xprt_destroy(xprt);
goto out;
return clnt;
}
/*
......
......@@ -371,13 +371,13 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
/* create transport and client */
xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
&server->addr, &timeparms);
if (xprt == NULL) {
if (IS_ERR(xprt)) {
printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
goto out_fail;
return (struct rpc_clnt *)xprt;
}
clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
server->rpc_ops->version, data->pseudoflavor);
if (clnt == NULL) {
if (IS_ERR(clnt)) {
printk(KERN_WARNING "NFS: cannot create RPC client.\n");
goto out_fail;
}
......@@ -390,9 +390,8 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
return clnt;
out_fail:
if (xprt)
xprt_destroy(xprt);
return NULL;
xprt_destroy(xprt);
return clnt;
}
/*
......@@ -1492,17 +1491,19 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
down_write(&clp->cl_sem);
if (clp->cl_rpcclient == NULL) {
xprt = xprt_create_proto(proto, &server->addr, &timeparms);
if (xprt == NULL) {
if (IS_ERR(xprt)) {
up_write(&clp->cl_sem);
printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
err = PTR_ERR(xprt);
goto out_fail;
}
clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
server->rpc_ops->version, authflavour);
if (clnt == NULL) {
if (IS_ERR(clnt)) {
up_write(&clp->cl_sem);
printk(KERN_WARNING "NFS: cannot create RPC client.\n");
xprt_destroy(xprt);
err = PTR_ERR(clnt);
goto out_fail;
}
clnt->cl_chatty = 1;
......@@ -1515,14 +1516,17 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
clear_bit(NFS4CLNT_OK, &clp->cl_state);
list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
clnt = rpc_clone_client(clp->cl_rpcclient);
server->nfs4_state = clp;
if (!IS_ERR(clnt))
server->nfs4_state = clp;
up_write(&clp->cl_sem);
clp = NULL;
if (clnt == NULL) {
if (IS_ERR(clnt)) {
printk(KERN_WARNING "NFS: cannot create RPC client.\n");
err = PTR_ERR(clnt);
goto out_remove_list;
}
err = -ENOMEM;
if (server->nfs4_state->cl_idmap == NULL) {
printk(KERN_WARNING "NFS: failed to create idmapper.\n");
goto out_shutdown;
......
......@@ -57,8 +57,9 @@ nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
(unsigned)ntohl(addr->sin_addr.s_addr), path);
sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
if (!(mnt_clnt = mnt_create(hostname, addr, version, protocol)))
return -EACCES;
mnt_clnt = mnt_create(hostname, addr, version, protocol);
if (IS_ERR(mnt_clnt))
return PTR_ERR(mnt_clnt);
call = (version == NFS_MNT3_VERSION) ? MOUNTPROC3_MNT : MNTPROC_MNT;
status = rpc_call(mnt_clnt, call, path, &result, 0);
......@@ -72,13 +73,14 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
if (!(xprt = xprt_create_proto(protocol, srvaddr, NULL)))
return NULL;
xprt = xprt_create_proto(protocol, srvaddr, NULL);
if (IS_ERR(xprt))
return (struct rpc_clnt *)xprt;
clnt = rpc_create_client(xprt, hostname,
&mnt_program, version,
RPC_AUTH_NULL);
if (!clnt) {
RPC_AUTH_UNIX);
if (IS_ERR(clnt)) {
xprt_destroy(xprt);
} else {
clnt->cl_softrtry = 1;
......
......@@ -102,19 +102,22 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
{
struct rpc_version *version;
struct rpc_clnt *clnt = NULL;
int err;
int len;
dprintk("RPC: creating %s client for %s (xprt %p)\n",
program->name, servname, xprt);
err = -EINVAL;
if (!xprt)
goto out;
goto out_err;
if (vers >= program->nrvers || !(version = program->version[vers]))
goto out;
goto out_err;
err = -ENOMEM;
clnt = (struct rpc_clnt *) kmalloc(sizeof(*clnt), GFP_KERNEL);
if (!clnt)
goto out_no_clnt;
goto out_err;
memset(clnt, 0, sizeof(*clnt));
atomic_set(&clnt->cl_users, 0);
atomic_set(&clnt->cl_count, 1);
......@@ -149,9 +152,11 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
clnt->cl_rtt = &clnt->cl_rtt_default;
rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval);
if (rpc_setup_pipedir(clnt, program->pipe_dir_name) < 0)
err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
if (err < 0)
goto out_no_path;
err = -ENOMEM;
if (!rpcauth_create(flavor, clnt)) {
printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
flavor);
......@@ -163,20 +168,16 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
if (clnt->cl_nodelen > UNX_MAXNODENAME)
clnt->cl_nodelen = UNX_MAXNODENAME;
memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
out:
return clnt;
out_no_clnt:
printk(KERN_INFO "RPC: out of memory in rpc_create_client\n");
goto out;
out_no_auth:
rpc_rmdir(clnt->cl_pathname);
out_no_path:
if (clnt->cl_server != clnt->cl_inline_name)
kfree(clnt->cl_server);
kfree(clnt);
clnt = NULL;
goto out;
out_err:
return ERR_PTR(err);
}
/*
......@@ -198,11 +199,10 @@ rpc_clone_client(struct rpc_clnt *clnt)
atomic_inc(&new->cl_parent->cl_count);
if (new->cl_auth)
atomic_inc(&new->cl_auth->au_count);
out:
return new;
out_no_clnt:
printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
goto out;
return ERR_PTR(-ENOMEM);
}
/*
......
......@@ -65,9 +65,11 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
map->pm_binding = 1;
spin_unlock(&pmap_lock);
task->tk_status = -EACCES; /* why set this? returns -EIO below */
if (!(pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot)))
pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot);
if (IS_ERR(pmap_clnt)) {
task->tk_status = PTR_ERR(pmap_clnt);
goto bailout;
}
task->tk_status = 0;
/*
......@@ -110,8 +112,9 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
if (!(pmap_clnt = pmap_create(hostname, sin, prot)))
return -EACCES;
pmap_clnt = pmap_create(hostname, sin, prot);
if (IS_ERR(pmap_clnt))
return PTR_ERR(pmap_clnt);
/* Setup the call info struct */
status = rpc_call(pmap_clnt, PMAP_GETPORT, &map, &map.pm_port, 0);
......@@ -161,16 +164,18 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
struct sockaddr_in sin;
struct rpc_portmap map;
struct rpc_clnt *pmap_clnt;
unsigned int error = 0;
int error = 0;
dprintk("RPC: registering (%d, %d, %d, %d) with portmapper.\n",
prog, vers, prot, port);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (!(pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP))) {
dprintk("RPC: couldn't create pmap client\n");
return -EACCES;
pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP);
if (IS_ERR(pmap_clnt)) {
error = PTR_ERR(pmap_clnt);
dprintk("RPC: couldn't create pmap client. Error = %d\n", error);
return error;
}
map.pm_prog = prog;
......@@ -199,15 +204,16 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
struct rpc_clnt *clnt;
/* printk("pmap: create xprt\n"); */
if (!(xprt = xprt_create_proto(proto, srvaddr, NULL)))
return NULL;
xprt = xprt_create_proto(proto, srvaddr, NULL);
if (IS_ERR(xprt))
return (struct rpc_clnt *)xprt;
xprt->addr.sin_port = htons(RPC_PMAP_PORT);
/* printk("pmap: create clnt\n"); */
clnt = rpc_create_client(xprt, hostname,
&pmap_program, RPC_PMAP_VERSION,
RPC_AUTH_NULL);
if (!clnt) {
if (IS_ERR(clnt)) {
xprt_destroy(xprt);
} else {
clnt->cl_softrtry = 1;
......
......@@ -1421,7 +1421,7 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
proto == IPPROTO_UDP? "UDP" : "TCP");
if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL)
return NULL;
return ERR_PTR(-ENOMEM);
memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */
xprt->addr = *ap;
......@@ -1597,16 +1597,11 @@ xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
struct rpc_xprt *xprt;
xprt = xprt_setup(proto, sap, to);
if (!xprt)
goto out_bad;
dprintk("RPC: xprt_create_proto created xprt %p\n", xprt);
if (IS_ERR(xprt))
dprintk("RPC: xprt_create_proto failed\n");
else
dprintk("RPC: xprt_create_proto created xprt %p\n", xprt);
return xprt;
out_bad:
dprintk("RPC: xprt_create_proto failed\n");
if (xprt)
kfree(xprt);
return NULL;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment