aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-08-22 20:06:10 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-09-22 23:24:33 -0400
commit24c8dbbb5f777187d660393599641ab3307b4b97 (patch)
tree9d50fdd57c7593d925a21e4bb049095a4e4ead6f /fs/nfs/super.c
parente9326dcab413848e70ab746c7c5363da13e5f801 (diff)
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>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c53
1 files changed, 21 insertions, 32 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 3ee85c4e65d8..f97d7d9c5c32 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1104,47 +1104,46 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1104 struct rpc_clnt *clnt = NULL; 1104 struct rpc_clnt *clnt = NULL;
1105 int err = -EIO; 1105 int err = -EIO;
1106 1106
1107 clp = nfs4_get_client(&server->addr.sin_addr); 1107 clp = nfs_get_client(server->hostname, &server->addr, 4);
1108 if (!clp) { 1108 if (!clp) {
1109 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__); 1109 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
1110 return ERR_PTR(err); 1110 return ERR_PTR(err);
1111 } 1111 }
1112 1112
1113 /* Now create transport and client */ 1113 /* Now create transport and client */
1114 down_write(&clp->cl_sem); 1114 if (clp->cl_cons_state == NFS_CS_INITING) {
1115 if (IS_ERR(clp->cl_rpcclient)) {
1116 xprt = xprt_create_proto(proto, &server->addr, timeparms); 1115 xprt = xprt_create_proto(proto, &server->addr, timeparms);
1117 if (IS_ERR(xprt)) { 1116 if (IS_ERR(xprt)) {
1118 up_write(&clp->cl_sem);
1119 err = PTR_ERR(xprt); 1117 err = PTR_ERR(xprt);
1120 dprintk("%s: cannot create RPC transport. Error = %d\n", 1118 dprintk("%s: cannot create RPC transport. Error = %d\n",
1121 __FUNCTION__, err); 1119 __FUNCTION__, err);
1122 goto out_fail; 1120 goto client_init_error;
1123 } 1121 }
1124 /* Bind to a reserved port! */ 1122 /* Bind to a reserved port! */
1125 xprt->resvport = 1; 1123 xprt->resvport = 1;
1126 clnt = rpc_create_client(xprt, server->hostname, &nfs_program, 1124 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
1127 server->rpc_ops->version, flavor); 1125 server->rpc_ops->version, flavor);
1128 if (IS_ERR(clnt)) { 1126 if (IS_ERR(clnt)) {
1129 up_write(&clp->cl_sem);
1130 err = PTR_ERR(clnt); 1127 err = PTR_ERR(clnt);
1131 dprintk("%s: cannot create RPC client. Error = %d\n", 1128 dprintk("%s: cannot create RPC client. Error = %d\n",
1132 __FUNCTION__, err); 1129 __FUNCTION__, err);
1133 goto out_fail; 1130 goto client_init_error;
1134 } 1131 }
1135 clnt->cl_intr = 1; 1132 clnt->cl_intr = 1;
1136 clnt->cl_softrtry = 1; 1133 clnt->cl_softrtry = 1;
1137 clp->cl_rpcclient = clnt; 1134 clp->cl_rpcclient = clnt;
1138 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); 1135 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
1139 if (nfs_idmap_new(clp) < 0) 1136 err = nfs_idmap_new(clp);
1140 goto out_fail; 1137 if (err < 0) {
1138 dprintk("%s: failed to create idmapper.\n",
1139 __FUNCTION__);
1140 goto client_init_error;
1141 }
1142 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
1143 nfs_mark_client_ready(clp, 0);
1141 } 1144 }
1142 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); 1145
1143 clnt = rpc_clone_client(clp->cl_rpcclient); 1146 clnt = rpc_clone_client(clp->cl_rpcclient);
1144 if (!IS_ERR(clnt))
1145 server->nfs_client = clp;
1146 up_write(&clp->cl_sem);
1147 clp = NULL;
1148 1147
1149 if (IS_ERR(clnt)) { 1148 if (IS_ERR(clnt)) {
1150 dprintk("%s: cannot create RPC client. Error = %d\n", 1149 dprintk("%s: cannot create RPC client. Error = %d\n",
@@ -1152,11 +1151,6 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1152 return clnt; 1151 return clnt;
1153 } 1152 }
1154 1153
1155 if (server->nfs_client->cl_idmap == NULL) {
1156 dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
1157 return ERR_PTR(-ENOMEM);
1158 }
1159
1160 if (clnt->cl_auth->au_flavor != flavor) { 1154 if (clnt->cl_auth->au_flavor != flavor) {
1161 struct rpc_auth *auth; 1155 struct rpc_auth *auth;
1162 1156
@@ -1166,11 +1160,16 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1166 return (struct rpc_clnt *)auth; 1160 return (struct rpc_clnt *)auth;
1167 } 1161 }
1168 } 1162 }
1163
1164 server->nfs_client = clp;
1165 down_write(&clp->cl_sem);
1166 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
1167 up_write(&clp->cl_sem);
1169 return clnt; 1168 return clnt;
1170 1169
1171 out_fail: 1170client_init_error:
1172 if (clp) 1171 nfs_mark_client_ready(clp, err);
1173 nfs4_put_client(clp); 1172 nfs_put_client(clp);
1174 return ERR_PTR(err); 1173 return ERR_PTR(err);
1175} 1174}
1176 1175
@@ -1329,14 +1328,6 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
1329 goto out_free; 1328 goto out_free;
1330 } 1329 }
1331 1330
1332 /* Fire up rpciod if not yet running */
1333 error = rpciod_up();
1334 if (error < 0) {
1335 dprintk("%s: couldn't start rpciod! Error = %d\n",
1336 __FUNCTION__, error);
1337 goto out_free;
1338 }
1339
1340 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); 1331 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
1341 if (IS_ERR(s)) { 1332 if (IS_ERR(s)) {
1342 error = PTR_ERR(s); 1333 error = PTR_ERR(s);
@@ -1383,8 +1374,6 @@ static void nfs4_kill_super(struct super_block *sb)
1383 1374
1384 destroy_nfsv4_state(server); 1375 destroy_nfsv4_state(server);
1385 1376
1386 rpciod_down();
1387
1388 nfs_free_iostats(server->io_stats); 1377 nfs_free_iostats(server->io_stats);
1389 kfree(server->hostname); 1378 kfree(server->hostname);
1390 kfree(server); 1379 kfree(server);