NFS: Generalise the nfs_client structure
Generalise the nfs_client structure by: (1) Moving nfs_client to a more general place (nfs_fs_sb.h). (2) Renaming its maintenance routines to be non-NFS4 specific. (3) Move those maintenance routines to a new non-NFS4 specific file (client.c) and move the declarations to internal.h. (4) Make nfs_find/get_client() take a full sockaddr_in to include the port number (will be required for NFS2/3). (5) Make nfs_find/get_client() take the NFS protocol version (again will be required to differentiate NFS2, 3 & 4 client records). Also: (6) Make nfs_client construction proceed akin to inodes, marking them as under construction and providing a function to indicate completion. (7) Make nfs_get_client() wait interruptibly if it finds a client that it can share, but that client is currently being constructed. (8) Make nfs4_create_client() use (6) and (7) instead of locking cl_sem. Signed-Off-By: David Howells <dhowells@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:

committed by
Trond Myklebust

parent
e9326dcab4
commit
24c8dbbb5f
@@ -1104,47 +1104,46 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
|
||||
struct rpc_clnt *clnt = NULL;
|
||||
int err = -EIO;
|
||||
|
||||
clp = nfs4_get_client(&server->addr.sin_addr);
|
||||
clp = nfs_get_client(server->hostname, &server->addr, 4);
|
||||
if (!clp) {
|
||||
dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* Now create transport and client */
|
||||
down_write(&clp->cl_sem);
|
||||
if (IS_ERR(clp->cl_rpcclient)) {
|
||||
if (clp->cl_cons_state == NFS_CS_INITING) {
|
||||
xprt = xprt_create_proto(proto, &server->addr, timeparms);
|
||||
if (IS_ERR(xprt)) {
|
||||
up_write(&clp->cl_sem);
|
||||
err = PTR_ERR(xprt);
|
||||
dprintk("%s: cannot create RPC transport. Error = %d\n",
|
||||
__FUNCTION__, err);
|
||||
goto out_fail;
|
||||
goto client_init_error;
|
||||
}
|
||||
/* Bind to a reserved port! */
|
||||
xprt->resvport = 1;
|
||||
clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
|
||||
server->rpc_ops->version, flavor);
|
||||
if (IS_ERR(clnt)) {
|
||||
up_write(&clp->cl_sem);
|
||||
err = PTR_ERR(clnt);
|
||||
dprintk("%s: cannot create RPC client. Error = %d\n",
|
||||
__FUNCTION__, err);
|
||||
goto out_fail;
|
||||
goto client_init_error;
|
||||
}
|
||||
clnt->cl_intr = 1;
|
||||
clnt->cl_softrtry = 1;
|
||||
clp->cl_rpcclient = clnt;
|
||||
memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
|
||||
if (nfs_idmap_new(clp) < 0)
|
||||
goto out_fail;
|
||||
err = nfs_idmap_new(clp);
|
||||
if (err < 0) {
|
||||
dprintk("%s: failed to create idmapper.\n",
|
||||
__FUNCTION__);
|
||||
goto client_init_error;
|
||||
}
|
||||
__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
|
||||
nfs_mark_client_ready(clp, 0);
|
||||
}
|
||||
list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
|
||||
|
||||
clnt = rpc_clone_client(clp->cl_rpcclient);
|
||||
if (!IS_ERR(clnt))
|
||||
server->nfs_client = clp;
|
||||
up_write(&clp->cl_sem);
|
||||
clp = NULL;
|
||||
|
||||
if (IS_ERR(clnt)) {
|
||||
dprintk("%s: cannot create RPC client. Error = %d\n",
|
||||
@@ -1152,11 +1151,6 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
|
||||
return clnt;
|
||||
}
|
||||
|
||||
if (server->nfs_client->cl_idmap == NULL) {
|
||||
dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
if (clnt->cl_auth->au_flavor != flavor) {
|
||||
struct rpc_auth *auth;
|
||||
|
||||
@@ -1166,11 +1160,16 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
|
||||
return (struct rpc_clnt *)auth;
|
||||
}
|
||||
}
|
||||
|
||||
server->nfs_client = clp;
|
||||
down_write(&clp->cl_sem);
|
||||
list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
|
||||
up_write(&clp->cl_sem);
|
||||
return clnt;
|
||||
|
||||
out_fail:
|
||||
if (clp)
|
||||
nfs4_put_client(clp);
|
||||
client_init_error:
|
||||
nfs_mark_client_ready(clp, err);
|
||||
nfs_put_client(clp);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
@@ -1329,14 +1328,6 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Fire up rpciod if not yet running */
|
||||
error = rpciod_up();
|
||||
if (error < 0) {
|
||||
dprintk("%s: couldn't start rpciod! Error = %d\n",
|
||||
__FUNCTION__, error);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
|
||||
if (IS_ERR(s)) {
|
||||
error = PTR_ERR(s);
|
||||
@@ -1383,8 +1374,6 @@ static void nfs4_kill_super(struct super_block *sb)
|
||||
|
||||
destroy_nfsv4_state(server);
|
||||
|
||||
rpciod_down();
|
||||
|
||||
nfs_free_iostats(server->io_stats);
|
||||
kfree(server->hostname);
|
||||
kfree(server);
|
||||
|
Reference in New Issue
Block a user