aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-04-24 14:28:18 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-04-24 14:28:18 -0400
commitfd954ae124e8a866e9cc1bc3de9a07be5492f608 (patch)
treeb45b1a58287e2e77afb1da4ed8ead0c3a8688c2d /fs/nfs/nfs4proc.c
parentfb8a5ba8114491467c4067ec0330e1c3dcc81d10 (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.c45
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
3768static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, 3767int 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
3793int 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
3813struct nfs4_delegreturndata { 3792struct 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