Skip to content

Commit dd99e9f

Browse files
author
Trond Myklebust
committed
NFSv4: Initialise connection to the server in nfs4_alloc_client()
Set up the connection to the NFSv4 server in nfs4_alloc_client(), before we've added the struct nfs_client to the net-namespace's nfs_client_list so that a downed server won't cause other mounts to hang in the trunking detection code. Reported-by: Michael Wakabayashi <mwakabayashi@vmware.com> Fixes: 5c6e5b6 ("NFS: Fix an Oops in the pNFS files and flexfiles connection setup to the DS") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 009c9aa commit dd99e9f

File tree

1 file changed

+42
-40
lines changed

1 file changed

+42
-40
lines changed

Diff for: fs/nfs/nfs4client.c

+42-40
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,11 @@ void nfs40_shutdown_client(struct nfs_client *clp)
197197

198198
struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
199199
{
200-
int err;
200+
char buf[INET6_ADDRSTRLEN + 1];
201+
const char *ip_addr = cl_init->ip_addr;
201202
struct nfs_client *clp = nfs_alloc_client(cl_init);
203+
int err;
204+
202205
if (IS_ERR(clp))
203206
return clp;
204207

@@ -222,6 +225,44 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
222225
init_waitqueue_head(&clp->cl_lock_waitq);
223226
#endif
224227
INIT_LIST_HEAD(&clp->pending_cb_stateids);
228+
229+
if (cl_init->minorversion != 0)
230+
__set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
231+
__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
232+
__set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
233+
234+
/*
235+
* Set up the connection to the server before we add add to the
236+
* global list.
237+
*/
238+
err = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_GSS_KRB5I);
239+
if (err == -EINVAL)
240+
err = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
241+
if (err < 0)
242+
goto error;
243+
244+
/* If no clientaddr= option was specified, find a usable cb address */
245+
if (ip_addr == NULL) {
246+
struct sockaddr_storage cb_addr;
247+
struct sockaddr *sap = (struct sockaddr *)&cb_addr;
248+
249+
err = rpc_localaddr(clp->cl_rpcclient, sap, sizeof(cb_addr));
250+
if (err < 0)
251+
goto error;
252+
err = rpc_ntop(sap, buf, sizeof(buf));
253+
if (err < 0)
254+
goto error;
255+
ip_addr = (const char *)buf;
256+
}
257+
strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
258+
259+
err = nfs_idmap_new(clp);
260+
if (err < 0) {
261+
dprintk("%s: failed to create idmapper. Error = %d\n",
262+
__func__, err);
263+
goto error;
264+
}
265+
__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
225266
return clp;
226267

227268
error:
@@ -372,52 +413,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
372413
struct nfs_client *nfs4_init_client(struct nfs_client *clp,
373414
const struct nfs_client_initdata *cl_init)
374415
{
375-
char buf[INET6_ADDRSTRLEN + 1];
376-
const char *ip_addr = cl_init->ip_addr;
377416
struct nfs_client *old;
378417
int error;
379418

380419
if (clp->cl_cons_state == NFS_CS_READY)
381420
/* the client is initialised already */
382421
return clp;
383422

384-
/* Check NFS protocol revision and initialize RPC op vector */
385-
clp->rpc_ops = &nfs_v4_clientops;
386-
387-
if (clp->cl_minorversion != 0)
388-
__set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
389-
__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
390-
__set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
391-
392-
error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_GSS_KRB5I);
393-
if (error == -EINVAL)
394-
error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
395-
if (error < 0)
396-
goto error;
397-
398-
/* If no clientaddr= option was specified, find a usable cb address */
399-
if (ip_addr == NULL) {
400-
struct sockaddr_storage cb_addr;
401-
struct sockaddr *sap = (struct sockaddr *)&cb_addr;
402-
403-
error = rpc_localaddr(clp->cl_rpcclient, sap, sizeof(cb_addr));
404-
if (error < 0)
405-
goto error;
406-
error = rpc_ntop(sap, buf, sizeof(buf));
407-
if (error < 0)
408-
goto error;
409-
ip_addr = (const char *)buf;
410-
}
411-
strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
412-
413-
error = nfs_idmap_new(clp);
414-
if (error < 0) {
415-
dprintk("%s: failed to create idmapper. Error = %d\n",
416-
__func__, error);
417-
goto error;
418-
}
419-
__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
420-
421423
error = nfs4_init_client_minor_version(clp);
422424
if (error < 0)
423425
goto error;

0 commit comments

Comments
 (0)