aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-23 15:52:14 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-23 15:52:14 -0400
commitb0212b84fb19cf89305ab96c73abdf3a76d05ef8 (patch)
tree429daec3f580ad8f4c39e90f212d259b19ba9394
parentbd1d421abcaae1b84ba377ea4c33bba31d654199 (diff)
parenteb04e0ac198cec3bab407ad220438dfa65c19c67 (diff)
Merge branch 'bugfixes' into linux-next
Fix up a conflict between the linux-next branch and mainline. Conflicts: fs/nfs/nfs4proc.c
-rw-r--r--fs/nfs/nfs4client.c45
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/nfs4state.c8
-rw-r--r--net/sunrpc/clnt.c11
4 files changed, 40 insertions, 25 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index c2b069e25819..947b0c908aa9 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -304,7 +304,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
304 struct rpc_cred *cred) 304 struct rpc_cred *cred)
305{ 305{
306 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); 306 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
307 struct nfs_client *pos, *n, *prev = NULL; 307 struct nfs_client *pos, *prev = NULL;
308 struct nfs4_setclientid_res clid = { 308 struct nfs4_setclientid_res clid = {
309 .clientid = new->cl_clientid, 309 .clientid = new->cl_clientid,
310 .confirm = new->cl_confirm, 310 .confirm = new->cl_confirm,
@@ -312,10 +312,23 @@ int nfs40_walk_client_list(struct nfs_client *new,
312 int status = -NFS4ERR_STALE_CLIENTID; 312 int status = -NFS4ERR_STALE_CLIENTID;
313 313
314 spin_lock(&nn->nfs_client_lock); 314 spin_lock(&nn->nfs_client_lock);
315 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { 315 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
316 /* If "pos" isn't marked ready, we can't trust the 316 /* If "pos" isn't marked ready, we can't trust the
317 * remaining fields in "pos" */ 317 * remaining fields in "pos" */
318 if (pos->cl_cons_state < NFS_CS_READY) 318 if (pos->cl_cons_state > NFS_CS_READY) {
319 atomic_inc(&pos->cl_count);
320 spin_unlock(&nn->nfs_client_lock);
321
322 if (prev)
323 nfs_put_client(prev);
324 prev = pos;
325
326 status = nfs_wait_client_init_complete(pos);
327 spin_lock(&nn->nfs_client_lock);
328 if (status < 0)
329 continue;
330 }
331 if (pos->cl_cons_state != NFS_CS_READY)
319 continue; 332 continue;
320 333
321 if (pos->rpc_ops != new->rpc_ops) 334 if (pos->rpc_ops != new->rpc_ops)
@@ -427,16 +440,16 @@ int nfs41_walk_client_list(struct nfs_client *new,
427 struct rpc_cred *cred) 440 struct rpc_cred *cred)
428{ 441{
429 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); 442 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
430 struct nfs_client *pos, *n, *prev = NULL; 443 struct nfs_client *pos, *prev = NULL;
431 int status = -NFS4ERR_STALE_CLIENTID; 444 int status = -NFS4ERR_STALE_CLIENTID;
432 445
433 spin_lock(&nn->nfs_client_lock); 446 spin_lock(&nn->nfs_client_lock);
434 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { 447 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
435 /* If "pos" isn't marked ready, we can't trust the 448 /* If "pos" isn't marked ready, we can't trust the
436 * remaining fields in "pos", especially the client 449 * remaining fields in "pos", especially the client
437 * ID and serverowner fields. Wait for CREATE_SESSION 450 * ID and serverowner fields. Wait for CREATE_SESSION
438 * to finish. */ 451 * to finish. */
439 if (pos->cl_cons_state < NFS_CS_READY) { 452 if (pos->cl_cons_state > NFS_CS_READY) {
440 atomic_inc(&pos->cl_count); 453 atomic_inc(&pos->cl_count);
441 spin_unlock(&nn->nfs_client_lock); 454 spin_unlock(&nn->nfs_client_lock);
442 455
@@ -444,18 +457,17 @@ int nfs41_walk_client_list(struct nfs_client *new,
444 nfs_put_client(prev); 457 nfs_put_client(prev);
445 prev = pos; 458 prev = pos;
446 459
447 nfs4_schedule_lease_recovery(pos);
448 status = nfs_wait_client_init_complete(pos); 460 status = nfs_wait_client_init_complete(pos);
449 if (status < 0) { 461 if (status == 0) {
450 nfs_put_client(pos); 462 nfs4_schedule_lease_recovery(pos);
451 spin_lock(&nn->nfs_client_lock); 463 status = nfs4_wait_clnt_recover(pos);
452 continue;
453 } 464 }
454 status = pos->cl_cons_state;
455 spin_lock(&nn->nfs_client_lock); 465 spin_lock(&nn->nfs_client_lock);
456 if (status < 0) 466 if (status < 0)
457 continue; 467 continue;
458 } 468 }
469 if (pos->cl_cons_state != NFS_CS_READY)
470 continue;
459 471
460 if (pos->rpc_ops != new->rpc_ops) 472 if (pos->rpc_ops != new->rpc_ops)
461 continue; 473 continue;
@@ -473,17 +485,18 @@ int nfs41_walk_client_list(struct nfs_client *new,
473 continue; 485 continue;
474 486
475 atomic_inc(&pos->cl_count); 487 atomic_inc(&pos->cl_count);
476 spin_unlock(&nn->nfs_client_lock); 488 *result = pos;
489 status = 0;
477 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", 490 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
478 __func__, pos, atomic_read(&pos->cl_count)); 491 __func__, pos, atomic_read(&pos->cl_count));
479 492 break;
480 *result = pos;
481 return 0;
482 } 493 }
483 494
484 /* No matching nfs_client found. */ 495 /* No matching nfs_client found. */
485 spin_unlock(&nn->nfs_client_lock); 496 spin_unlock(&nn->nfs_client_lock);
486 dprintk("NFS: <-- %s status = %d\n", __func__, status); 497 dprintk("NFS: <-- %s status = %d\n", __func__, status);
498 if (prev)
499 nfs_put_client(prev);
487 return status; 500 return status;
488} 501}
489#endif /* CONFIG_NFS_V4_1 */ 502#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e13b7ccee98d..3bc847ce4838 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1102,6 +1102,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1102 /* Save the delegation */ 1102 /* Save the delegation */
1103 nfs4_stateid_copy(&stateid, &delegation->stateid); 1103 nfs4_stateid_copy(&stateid, &delegation->stateid);
1104 rcu_read_unlock(); 1104 rcu_read_unlock();
1105 nfs_release_seqid(opendata->o_arg.seqid);
1105 if (!opendata->is_recover) { 1106 if (!opendata->is_recover) {
1106 ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); 1107 ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
1107 if (ret != 0) 1108 if (ret != 0)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 7a74ea64bf54..0b32f9483b7a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1897,7 +1897,13 @@ again:
1897 status = PTR_ERR(clnt); 1897 status = PTR_ERR(clnt);
1898 break; 1898 break;
1899 } 1899 }
1900 clp->cl_rpcclient = clnt; 1900 /* Note: this is safe because we haven't yet marked the
1901 * client as ready, so we are the only user of
1902 * clp->cl_rpcclient
1903 */
1904 clnt = xchg(&clp->cl_rpcclient, clnt);
1905 rpc_shutdown_client(clnt);
1906 clnt = clp->cl_rpcclient;
1901 goto again; 1907 goto again;
1902 1908
1903 case -NFS4ERR_MINOR_VERS_MISMATCH: 1909 case -NFS4ERR_MINOR_VERS_MISMATCH:
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 651245aa829a..d259fa966927 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -304,10 +304,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
304 err = rpciod_up(); 304 err = rpciod_up();
305 if (err) 305 if (err)
306 goto out_no_rpciod; 306 goto out_no_rpciod;
307 err = -EINVAL;
308 if (!xprt)
309 goto out_no_xprt;
310 307
308 err = -EINVAL;
311 if (args->version >= program->nrvers) 309 if (args->version >= program->nrvers)
312 goto out_err; 310 goto out_err;
313 version = program->version[args->version]; 311 version = program->version[args->version];
@@ -382,10 +380,9 @@ out_no_principal:
382out_no_stats: 380out_no_stats:
383 kfree(clnt); 381 kfree(clnt);
384out_err: 382out_err:
385 xprt_put(xprt);
386out_no_xprt:
387 rpciod_down(); 383 rpciod_down();
388out_no_rpciod: 384out_no_rpciod:
385 xprt_put(xprt);
389 return ERR_PTR(err); 386 return ERR_PTR(err);
390} 387}
391 388
@@ -514,7 +511,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
514 new = rpc_new_client(args, xprt); 511 new = rpc_new_client(args, xprt);
515 if (IS_ERR(new)) { 512 if (IS_ERR(new)) {
516 err = PTR_ERR(new); 513 err = PTR_ERR(new);
517 goto out_put; 514 goto out_err;
518 } 515 }
519 516
520 atomic_inc(&clnt->cl_count); 517 atomic_inc(&clnt->cl_count);
@@ -527,8 +524,6 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
527 new->cl_chatty = clnt->cl_chatty; 524 new->cl_chatty = clnt->cl_chatty;
528 return new; 525 return new;
529 526
530out_put:
531 xprt_put(xprt);
532out_err: 527out_err:
533 dprintk("RPC: %s: returned error %d\n", __func__, err); 528 dprintk("RPC: %s: returned error %d\n", __func__, err);
534 return ERR_PTR(err); 529 return ERR_PTR(err);