diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-23 13:26:10 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-23 15:24:59 -0400 |
commit | 54ac471c83aff6b1e068eb8029c797dc68a76e89 (patch) | |
tree | 3311a74fc6f5cdbedbe4e1da9bbbbaf6671050a2 /fs/nfs | |
parent | 4697bd5e9419348ef9fa9b55cefe4355ad9d3d01 (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.c | 5 | ||||
-rw-r--r-- | fs/nfs/idmap.c | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 1 |
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 | */ |
598 | void nfs_mark_client_ready(struct nfs_client *clp, int state) | 602 | void 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 | ||