Loading fs/nfs/nfs4client.c +29 −16 Original line number Diff line number Diff line Loading @@ -304,7 +304,7 @@ int nfs40_walk_client_list(struct nfs_client *new, struct rpc_cred *cred) { struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); struct nfs_client *pos, *n, *prev = NULL; struct nfs_client *pos, *prev = NULL; struct nfs4_setclientid_res clid = { .clientid = new->cl_clientid, .confirm = new->cl_confirm, Loading @@ -312,10 +312,23 @@ int nfs40_walk_client_list(struct nfs_client *new, int status = -NFS4ERR_STALE_CLIENTID; spin_lock(&nn->nfs_client_lock); list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { /* If "pos" isn't marked ready, we can't trust the * remaining fields in "pos" */ if (pos->cl_cons_state < NFS_CS_READY) if (pos->cl_cons_state > NFS_CS_READY) { atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); if (prev) nfs_put_client(prev); prev = pos; status = nfs_wait_client_init_complete(pos); spin_lock(&nn->nfs_client_lock); if (status < 0) continue; } if (pos->cl_cons_state != NFS_CS_READY) continue; if (pos->rpc_ops != new->rpc_ops) Loading Loading @@ -427,16 +440,16 @@ int nfs41_walk_client_list(struct nfs_client *new, struct rpc_cred *cred) { struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); struct nfs_client *pos, *n, *prev = NULL; struct nfs_client *pos, *prev = NULL; int status = -NFS4ERR_STALE_CLIENTID; spin_lock(&nn->nfs_client_lock); list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { /* If "pos" isn't marked ready, we can't trust the * remaining fields in "pos", especially the client * ID and serverowner fields. Wait for CREATE_SESSION * to finish. */ if (pos->cl_cons_state < NFS_CS_READY) { if (pos->cl_cons_state > NFS_CS_READY) { atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); Loading @@ -444,18 +457,17 @@ int nfs41_walk_client_list(struct nfs_client *new, nfs_put_client(prev); prev = pos; nfs4_schedule_lease_recovery(pos); status = nfs_wait_client_init_complete(pos); if (status < 0) { nfs_put_client(pos); spin_lock(&nn->nfs_client_lock); continue; if (status == 0) { nfs4_schedule_lease_recovery(pos); status = nfs4_wait_clnt_recover(pos); } status = pos->cl_cons_state; spin_lock(&nn->nfs_client_lock); if (status < 0) continue; } if (pos->cl_cons_state != NFS_CS_READY) continue; if (pos->rpc_ops != new->rpc_ops) continue; Loading @@ -473,17 +485,18 @@ int nfs41_walk_client_list(struct nfs_client *new, continue; atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); *result = pos; status = 0; dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", __func__, pos, atomic_read(&pos->cl_count)); *result = pos; return 0; break; } /* No matching nfs_client found. */ spin_unlock(&nn->nfs_client_lock); dprintk("NFS: <-- %s status = %d\n", __func__, status); if (prev) nfs_put_client(prev); return status; } #endif /* CONFIG_NFS_V4_1 */ Loading fs/nfs/nfs4proc.c +1 −0 Original line number Diff line number Diff line Loading @@ -1102,6 +1102,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) /* Save the delegation */ nfs4_stateid_copy(&stateid, &delegation->stateid); rcu_read_unlock(); nfs_release_seqid(opendata->o_arg.seqid); if (!opendata->is_recover) { ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); if (ret != 0) Loading fs/nfs/nfs4state.c +7 −1 Original line number Diff line number Diff line Loading @@ -1897,7 +1897,13 @@ again: status = PTR_ERR(clnt); break; } clp->cl_rpcclient = clnt; /* Note: this is safe because we haven't yet marked the * client as ready, so we are the only user of * clp->cl_rpcclient */ clnt = xchg(&clp->cl_rpcclient, clnt); rpc_shutdown_client(clnt); clnt = clp->cl_rpcclient; goto again; case -NFS4ERR_MINOR_VERS_MISMATCH: Loading net/sunrpc/clnt.c +3 −8 Original line number Diff line number Diff line Loading @@ -304,10 +304,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru err = rpciod_up(); if (err) goto out_no_rpciod; err = -EINVAL; if (!xprt) goto out_no_xprt; err = -EINVAL; if (args->version >= program->nrvers) goto out_err; version = program->version[args->version]; Loading Loading @@ -382,10 +380,9 @@ out_no_principal: out_no_stats: kfree(clnt); out_err: xprt_put(xprt); out_no_xprt: rpciod_down(); out_no_rpciod: xprt_put(xprt); return ERR_PTR(err); } Loading Loading @@ -514,7 +511,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, new = rpc_new_client(args, xprt); if (IS_ERR(new)) { err = PTR_ERR(new); goto out_put; goto out_err; } atomic_inc(&clnt->cl_count); Loading @@ -527,8 +524,6 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, new->cl_chatty = clnt->cl_chatty; return new; out_put: xprt_put(xprt); out_err: dprintk("RPC: %s: returned error %d\n", __func__, err); return ERR_PTR(err); Loading Loading
fs/nfs/nfs4client.c +29 −16 Original line number Diff line number Diff line Loading @@ -304,7 +304,7 @@ int nfs40_walk_client_list(struct nfs_client *new, struct rpc_cred *cred) { struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); struct nfs_client *pos, *n, *prev = NULL; struct nfs_client *pos, *prev = NULL; struct nfs4_setclientid_res clid = { .clientid = new->cl_clientid, .confirm = new->cl_confirm, Loading @@ -312,10 +312,23 @@ int nfs40_walk_client_list(struct nfs_client *new, int status = -NFS4ERR_STALE_CLIENTID; spin_lock(&nn->nfs_client_lock); list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { /* If "pos" isn't marked ready, we can't trust the * remaining fields in "pos" */ if (pos->cl_cons_state < NFS_CS_READY) if (pos->cl_cons_state > NFS_CS_READY) { atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); if (prev) nfs_put_client(prev); prev = pos; status = nfs_wait_client_init_complete(pos); spin_lock(&nn->nfs_client_lock); if (status < 0) continue; } if (pos->cl_cons_state != NFS_CS_READY) continue; if (pos->rpc_ops != new->rpc_ops) Loading Loading @@ -427,16 +440,16 @@ int nfs41_walk_client_list(struct nfs_client *new, struct rpc_cred *cred) { struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); struct nfs_client *pos, *n, *prev = NULL; struct nfs_client *pos, *prev = NULL; int status = -NFS4ERR_STALE_CLIENTID; spin_lock(&nn->nfs_client_lock); list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { /* If "pos" isn't marked ready, we can't trust the * remaining fields in "pos", especially the client * ID and serverowner fields. Wait for CREATE_SESSION * to finish. */ if (pos->cl_cons_state < NFS_CS_READY) { if (pos->cl_cons_state > NFS_CS_READY) { atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); Loading @@ -444,18 +457,17 @@ int nfs41_walk_client_list(struct nfs_client *new, nfs_put_client(prev); prev = pos; nfs4_schedule_lease_recovery(pos); status = nfs_wait_client_init_complete(pos); if (status < 0) { nfs_put_client(pos); spin_lock(&nn->nfs_client_lock); continue; if (status == 0) { nfs4_schedule_lease_recovery(pos); status = nfs4_wait_clnt_recover(pos); } status = pos->cl_cons_state; spin_lock(&nn->nfs_client_lock); if (status < 0) continue; } if (pos->cl_cons_state != NFS_CS_READY) continue; if (pos->rpc_ops != new->rpc_ops) continue; Loading @@ -473,17 +485,18 @@ int nfs41_walk_client_list(struct nfs_client *new, continue; atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); *result = pos; status = 0; dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", __func__, pos, atomic_read(&pos->cl_count)); *result = pos; return 0; break; } /* No matching nfs_client found. */ spin_unlock(&nn->nfs_client_lock); dprintk("NFS: <-- %s status = %d\n", __func__, status); if (prev) nfs_put_client(prev); return status; } #endif /* CONFIG_NFS_V4_1 */ Loading
fs/nfs/nfs4proc.c +1 −0 Original line number Diff line number Diff line Loading @@ -1102,6 +1102,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) /* Save the delegation */ nfs4_stateid_copy(&stateid, &delegation->stateid); rcu_read_unlock(); nfs_release_seqid(opendata->o_arg.seqid); if (!opendata->is_recover) { ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); if (ret != 0) Loading
fs/nfs/nfs4state.c +7 −1 Original line number Diff line number Diff line Loading @@ -1897,7 +1897,13 @@ again: status = PTR_ERR(clnt); break; } clp->cl_rpcclient = clnt; /* Note: this is safe because we haven't yet marked the * client as ready, so we are the only user of * clp->cl_rpcclient */ clnt = xchg(&clp->cl_rpcclient, clnt); rpc_shutdown_client(clnt); clnt = clp->cl_rpcclient; goto again; case -NFS4ERR_MINOR_VERS_MISMATCH: Loading
net/sunrpc/clnt.c +3 −8 Original line number Diff line number Diff line Loading @@ -304,10 +304,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru err = rpciod_up(); if (err) goto out_no_rpciod; err = -EINVAL; if (!xprt) goto out_no_xprt; err = -EINVAL; if (args->version >= program->nrvers) goto out_err; version = program->version[args->version]; Loading Loading @@ -382,10 +380,9 @@ out_no_principal: out_no_stats: kfree(clnt); out_err: xprt_put(xprt); out_no_xprt: rpciod_down(); out_no_rpciod: xprt_put(xprt); return ERR_PTR(err); } Loading Loading @@ -514,7 +511,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, new = rpc_new_client(args, xprt); if (IS_ERR(new)) { err = PTR_ERR(new); goto out_put; goto out_err; } atomic_inc(&clnt->cl_count); Loading @@ -527,8 +524,6 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, new->cl_chatty = clnt->cl_chatty; return new; out_put: xprt_put(xprt); out_err: dprintk("RPC: %s: returned error %d\n", __func__, err); return ERR_PTR(err); Loading