浏览代码

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>
Trond Myklebust 13 年之前
父节点
当前提交
54ac471c83
共有 3 个文件被更改,包括 7 次插入0 次删除
  1. 5 0
      fs/nfs/client.c
  2. 1 0
      fs/nfs/idmap.c
  3. 1 0
      fs/nfs/nfs4proc.c

+ 5 - 0
fs/nfs/client.c

@@ -459,6 +459,8 @@ static bool nfs4_cb_match_client(const struct sockaddr *addr,
 	    clp->cl_cons_state == NFS_CS_SESSION_INITING))
 	    clp->cl_cons_state == NFS_CS_SESSION_INITING))
 		return false;
 		return false;
 
 
+	smp_rmb();
+
 	/* Match the version and minorversion */
 	/* Match the version and minorversion */
 	if (clp->rpc_ops->version != 4 ||
 	if (clp->rpc_ops->version != 4 ||
 	    clp->cl_minorversion != minorversion)
 	    clp->cl_minorversion != minorversion)
@@ -539,6 +541,8 @@ nfs_found_client(const struct nfs_client_initdata *cl_init,
 		return ERR_PTR(error);
 		return ERR_PTR(error);
 	}
 	}
 
 
+	smp_rmb();
+
 	BUG_ON(clp->cl_cons_state != NFS_CS_READY);
 	BUG_ON(clp->cl_cons_state != NFS_CS_READY);
 
 
 	dprintk("<-- %s found nfs_client %p for %s\n",
 	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)
 void nfs_mark_client_ready(struct nfs_client *clp, int state)
 {
 {
+	smp_wmb();
 	clp->cl_cons_state = state;
 	clp->cl_cons_state = state;
 	wake_up_all(&nfs_client_active_wq);
 	wake_up_all(&nfs_client_active_wq);
 }
 }

+ 1 - 0
fs/nfs/idmap.c

@@ -548,6 +548,7 @@ restart:
 		/* Skip nfs_clients that failed to initialise */
 		/* Skip nfs_clients that failed to initialise */
 		if (clp->cl_cons_state < 0)
 		if (clp->cl_cons_state < 0)
 			continue;
 			continue;
+		smp_rmb();
 		if (clp->rpc_ops != &nfs_v4_clientops)
 		if (clp->rpc_ops != &nfs_v4_clientops)
 			continue;
 			continue;
 		cl_dentry = clp->cl_idmap->idmap_pipe->dentry;
 		cl_dentry = clp->cl_idmap->idmap_pipe->dentry;

+ 1 - 0
fs/nfs/nfs4proc.c

@@ -5621,6 +5621,7 @@ static int nfs41_check_session_ready(struct nfs_client *clp)
 	}
 	}
 	if (clp->cl_cons_state < NFS_CS_READY)
 	if (clp->cl_cons_state < NFS_CS_READY)
 		return -EPROTONOSUPPORT;
 		return -EPROTONOSUPPORT;
+	smp_rmb();
 	return 0;
 	return 0;
 }
 }