NFS: make nfs_match_client killable
Actually we don't do anything with return value from nfs_wait_client_init_complete in nfs_match_client, as a consequence if we get a fatal signal and client is not fully initialised, we'll loop to "again" label This has been proven to cause soft lockups on some scenarios (no-carrier but configured network interfaces) Signed-off-by: Roberto Bergantinos Corpas <rbergant@redhat.com> Reviewed-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
b422df915c
commit
950a578c61
|
@ -284,6 +284,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
|
|||
struct nfs_client *clp;
|
||||
const struct sockaddr *sap = data->addr;
|
||||
struct nfs_net *nn = net_generic(data->net, nfs_net_id);
|
||||
int error;
|
||||
|
||||
again:
|
||||
list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
|
||||
|
@ -296,8 +297,10 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
|
|||
if (clp->cl_cons_state > NFS_CS_READY) {
|
||||
refcount_inc(&clp->cl_count);
|
||||
spin_unlock(&nn->nfs_client_lock);
|
||||
nfs_wait_client_init_complete(clp);
|
||||
error = nfs_wait_client_init_complete(clp);
|
||||
nfs_put_client(clp);
|
||||
if (error < 0)
|
||||
return ERR_PTR(error);
|
||||
spin_lock(&nn->nfs_client_lock);
|
||||
goto again;
|
||||
}
|
||||
|
@ -407,6 +410,8 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
|
|||
clp = nfs_match_client(cl_init);
|
||||
if (clp) {
|
||||
spin_unlock(&nn->nfs_client_lock);
|
||||
if (IS_ERR(clp))
|
||||
return clp;
|
||||
if (new)
|
||||
new->rpc_ops->free_client(new);
|
||||
return nfs_found_client(cl_init, clp);
|
||||
|
|
Loading…
Reference in New Issue