aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-23 13:26:10 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-23 15:24:59 -0400
commit54ac471c83aff6b1e068eb8029c797dc68a76e89 (patch)
tree3311a74fc6f5cdbedbe4e1da9bbbbaf6671050a2 /fs/nfs
parent4697bd5e9419348ef9fa9b55cefe4355ad9d3d01 (diff)
NFS: Add memory barriers to the nfs_client->cl_cons_state initialisation
Ensure that a process that uses the nfs_client->cl_cons_state test for whether the initialisation process is finished does not read stale data. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c5
-rw-r--r--fs/nfs/idmap.c1
-rw-r--r--fs/nfs/nfs4proc.c1
3 files changed, 7 insertions, 0 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index d35664287e14..a50bdfbbc429 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -459,6 +459,8 @@ static bool nfs4_cb_match_client(const struct sockaddr *addr,
459 clp->cl_cons_state == NFS_CS_SESSION_INITING)) 459 clp->cl_cons_state == NFS_CS_SESSION_INITING))
460 return false; 460 return false;
461 461
462 smp_rmb();
463
462 /* Match the version and minorversion */ 464 /* Match the version and minorversion */
463 if (clp->rpc_ops->version != 4 || 465 if (clp->rpc_ops->version != 4 ||
464 clp->cl_minorversion != minorversion) 466 clp->cl_minorversion != minorversion)
@@ -539,6 +541,8 @@ nfs_found_client(const struct nfs_client_initdata *cl_init,
539 return ERR_PTR(error); 541 return ERR_PTR(error);
540 } 542 }
541 543
544 smp_rmb();
545
542 BUG_ON(clp->cl_cons_state != NFS_CS_READY); 546 BUG_ON(clp->cl_cons_state != NFS_CS_READY);
543 547
544 dprintk("<-- %s found nfs_client %p for %s\n", 548 dprintk("<-- %s found nfs_client %p for %s\n",
@@ -597,6 +601,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
597 */ 601 */
598void nfs_mark_client_ready(struct nfs_client *clp, int state) 602void nfs_mark_client_ready(struct nfs_client *clp, int state)
599{ 603{
604 smp_wmb();
600 clp->cl_cons_state = state; 605 clp->cl_cons_state = state;
601 wake_up_all(&nfs_client_active_wq); 606 wake_up_all(&nfs_client_active_wq);
602} 607}
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 861be75eb165..b5b86a05059c 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -548,6 +548,7 @@ restart:
548 /* Skip nfs_clients that failed to initialise */ 548 /* Skip nfs_clients that failed to initialise */
549 if (clp->cl_cons_state < 0) 549 if (clp->cl_cons_state < 0)
550 continue; 550 continue;
551 smp_rmb();
551 if (clp->rpc_ops != &nfs_v4_clientops) 552 if (clp->rpc_ops != &nfs_v4_clientops)
552 continue; 553 continue;
553 cl_dentry = clp->cl_idmap->idmap_pipe->dentry; 554 cl_dentry = clp->cl_idmap->idmap_pipe->dentry;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c856298def7d..8f39bb3ca1b3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5621,6 +5621,7 @@ static int nfs41_check_session_ready(struct nfs_client *clp)
5621 } 5621 }
5622 if (clp->cl_cons_state < NFS_CS_READY) 5622 if (clp->cl_cons_state < NFS_CS_READY)
5623 return -EPROTONOSUPPORT; 5623 return -EPROTONOSUPPORT;
5624 smp_rmb();
5624 return 0; 5625 return 0;
5625} 5626}
5626 5627