From 4697bd5e9419348ef9fa9b55cefe4355ad9d3d01 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 23 May 2012 13:24:36 -0400 Subject: NFSv4: Fix a race in the net namespace mount notification Since the struct nfs_client gets added to the global nfs_client_list before it is initialised, it is possible that rpc_pipefs_event can end up trying to create idmapper entries on such a thing. The solution is to have the mount notification wait for the initialisation of each nfs_client to complete, and then to skip any entries for which the it failed. Reported-by: Stanislav Kinsbursky Signed-off-by: Trond Myklebust Acked-by: Stanislav Kinsbursky --- fs/nfs/idmap.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'fs/nfs/idmap.c') diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 2eaecf9d8db7..861be75eb165 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -530,9 +530,24 @@ static struct nfs_client *nfs_get_client_for_event(struct net *net, int event) struct nfs_net *nn = net_generic(net, nfs_net_id); struct dentry *cl_dentry; struct nfs_client *clp; + int err; +restart: spin_lock(&nn->nfs_client_lock); list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { + /* Wait for initialisation to finish */ + if (clp->cl_cons_state == NFS_CS_INITING) { + atomic_inc(&clp->cl_count); + spin_unlock(&nn->nfs_client_lock); + err = nfs_wait_client_init_complete(clp); + nfs_put_client(clp); + if (err) + return NULL; + goto restart; + } + /* Skip nfs_clients that failed to initialise */ + if (clp->cl_cons_state < 0) + continue; if (clp->rpc_ops != &nfs_v4_clientops) continue; cl_dentry = clp->cl_idmap->idmap_pipe->dentry; -- cgit v1.2.3