diff options
author | David Howells <dhowells@redhat.com> | 2006-08-22 20:06:10 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-09-22 23:24:33 -0400 |
commit | 24c8dbbb5f777187d660393599641ab3307b4b97 (patch) | |
tree | 9d50fdd57c7593d925a21e4bb049095a4e4ead6f /fs/nfs/super.c | |
parent | e9326dcab413848e70ab746c7c5363da13e5f801 (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.c | 53 |
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: | 1170 | client_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); |