NFS: Add memory barriers to the nfs_client->cl_cons_state initialisation
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 23 May 2012 17:26:10 +0000 (13:26 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 23 May 2012 19:24:59 +0000 (15:24 -0400)
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>
fs/nfs/client.c
fs/nfs/idmap.c
fs/nfs/nfs4proc.c

index d35664287e14cfe4189199e9cbe2769f699274bc..a50bdfbbc4295d8ca3486b243ad8c23bb2b06887 100644 (file)
@@ -459,6 +459,8 @@ static bool nfs4_cb_match_client(const struct sockaddr *addr,
            clp->cl_cons_state == NFS_CS_SESSION_INITING))
                return false;
 
+       smp_rmb();
+
        /* Match the version and minorversion */
        if (clp->rpc_ops->version != 4 ||
            clp->cl_minorversion != minorversion)
@@ -539,6 +541,8 @@ nfs_found_client(const struct nfs_client_initdata *cl_init,
                return ERR_PTR(error);
        }
 
+       smp_rmb();
+
        BUG_ON(clp->cl_cons_state != NFS_CS_READY);
 
        dprintk("<-- %s found nfs_client %p for %s\n",
@@ -597,6 +601,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
  */
 void nfs_mark_client_ready(struct nfs_client *clp, int state)
 {
+       smp_wmb();
        clp->cl_cons_state = state;
        wake_up_all(&nfs_client_active_wq);
 }
index 861be75eb1650a5437ab3a9320bd0fbd488036f3..b5b86a05059c8c0cf157495878bad3621a25a8dc 100644 (file)
@@ -548,6 +548,7 @@ restart:
                /* Skip nfs_clients that failed to initialise */
                if (clp->cl_cons_state < 0)
                        continue;
+               smp_rmb();
                if (clp->rpc_ops != &nfs_v4_clientops)
                        continue;
                cl_dentry = clp->cl_idmap->idmap_pipe->dentry;
index c856298def7d3a0592484c705fc3eb00abc62a35..8f39bb3ca1b31ce177d4a4321a90f79aa500e922 100644 (file)
@@ -5621,6 +5621,7 @@ static int nfs41_check_session_ready(struct nfs_client *clp)
        }
        if (clp->cl_cons_state < NFS_CS_READY)
                return -EPROTONOSUPPORT;
+       smp_rmb();
        return 0;
 }