diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-04-24 14:28:18 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-04-24 14:28:18 -0400 |
commit | fd954ae124e8a866e9cc1bc3de9a07be5492f608 (patch) | |
tree | b45b1a58287e2e77afb1da4ed8ead0c3a8688c2d /fs/nfs/nfs4proc.c | |
parent | fb8a5ba8114491467c4067ec0330e1c3dcc81d10 (diff) |
NFSv4.1: Don't loop forever in nfs4_proc_create_session
If a server for some reason keeps sending NFS4ERR_DELAY errors, we can end
up looping forever inside nfs4_proc_create_session, and so the usual
mechanisms for detecting if the nfs_client is dead don't work.
Fix this by ensuring that we loop inside the nfs4_state_manager thread
instead.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 45 |
1 files changed, 7 insertions, 38 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 628e35f75307..50c814828fcb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3754,18 +3754,17 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, | |||
3754 | status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); | 3754 | status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); |
3755 | if (status != -NFS4ERR_CLID_INUSE) | 3755 | if (status != -NFS4ERR_CLID_INUSE) |
3756 | break; | 3756 | break; |
3757 | if (signalled()) | 3757 | if (loop != 0) { |
3758 | ++clp->cl_id_uniquifier; | ||
3758 | break; | 3759 | break; |
3759 | if (loop++ & 1) | 3760 | } |
3760 | ssleep(clp->cl_lease_time / HZ + 1); | 3761 | ++loop; |
3761 | else | 3762 | ssleep(clp->cl_lease_time / HZ + 1); |
3762 | if (++clp->cl_id_uniquifier == 0) | ||
3763 | break; | ||
3764 | } | 3763 | } |
3765 | return status; | 3764 | return status; |
3766 | } | 3765 | } |
3767 | 3766 | ||
3768 | static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, | 3767 | int nfs4_proc_setclientid_confirm(struct nfs_client *clp, |
3769 | struct nfs4_setclientid_res *arg, | 3768 | struct nfs4_setclientid_res *arg, |
3770 | struct rpc_cred *cred) | 3769 | struct rpc_cred *cred) |
3771 | { | 3770 | { |
@@ -3790,26 +3789,6 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, | |||
3790 | return status; | 3789 | return status; |
3791 | } | 3790 | } |
3792 | 3791 | ||
3793 | int nfs4_proc_setclientid_confirm(struct nfs_client *clp, | ||
3794 | struct nfs4_setclientid_res *arg, | ||
3795 | struct rpc_cred *cred) | ||
3796 | { | ||
3797 | long timeout = 0; | ||
3798 | int err; | ||
3799 | do { | ||
3800 | err = _nfs4_proc_setclientid_confirm(clp, arg, cred); | ||
3801 | switch (err) { | ||
3802 | case 0: | ||
3803 | return err; | ||
3804 | case -NFS4ERR_RESOURCE: | ||
3805 | /* The IBM lawyers misread another document! */ | ||
3806 | case -NFS4ERR_DELAY: | ||
3807 | err = nfs4_delay(clp->cl_rpcclient, &timeout); | ||
3808 | } | ||
3809 | } while (err == 0); | ||
3810 | return err; | ||
3811 | } | ||
3812 | |||
3813 | struct nfs4_delegreturndata { | 3792 | struct nfs4_delegreturndata { |
3814 | struct nfs4_delegreturnargs args; | 3793 | struct nfs4_delegreturnargs args; |
3815 | struct nfs4_delegreturnres res; | 3794 | struct nfs4_delegreturnres res; |
@@ -5222,20 +5201,10 @@ int nfs4_proc_create_session(struct nfs_client *clp) | |||
5222 | int status; | 5201 | int status; |
5223 | unsigned *ptr; | 5202 | unsigned *ptr; |
5224 | struct nfs4_session *session = clp->cl_session; | 5203 | struct nfs4_session *session = clp->cl_session; |
5225 | long timeout = 0; | ||
5226 | int err; | ||
5227 | 5204 | ||
5228 | dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); | 5205 | dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); |
5229 | 5206 | ||
5230 | do { | 5207 | status = _nfs4_proc_create_session(clp); |
5231 | status = _nfs4_proc_create_session(clp); | ||
5232 | if (status == -NFS4ERR_DELAY) { | ||
5233 | err = nfs4_delay(clp->cl_rpcclient, &timeout); | ||
5234 | if (err) | ||
5235 | status = err; | ||
5236 | } | ||
5237 | } while (status == -NFS4ERR_DELAY); | ||
5238 | |||
5239 | if (status) | 5208 | if (status) |
5240 | goto out; | 5209 | goto out; |
5241 | 5210 | ||