Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54ac471c authored by Trond Myklebust's avatar Trond Myklebust
Browse files

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 4697bd5e
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -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
Original line number Original line Diff line number Diff line
@@ -548,6 +548,7 @@ static struct nfs_client *nfs_get_client_for_event(struct net *net, int event)
		/* 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
Original line number Original line Diff line number Diff line
@@ -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;
}
}