aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4_fs.h1
-rw-r--r--fs/nfs/nfs4proc.c45
-rw-r--r--fs/nfs/nfs4state.c46
-rw-r--r--include/linux/nfs_fs_sb.h1
4 files changed, 40 insertions, 53 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index e1c261ddd65d..c4a69833dd0d 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -47,6 +47,7 @@ enum nfs4_client_state {
47 NFS4CLNT_LAYOUTRECALL, 47 NFS4CLNT_LAYOUTRECALL,
48 NFS4CLNT_SESSION_RESET, 48 NFS4CLNT_SESSION_RESET,
49 NFS4CLNT_RECALL_SLOT, 49 NFS4CLNT_RECALL_SLOT,
50 NFS4CLNT_LEASE_CONFIRM,
50}; 51};
51 52
52enum nfs4_session_state { 53enum nfs4_session_state {
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
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 4dfb34b43ffb..4a810c8b0753 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -64,10 +64,15 @@ static LIST_HEAD(nfs4_clientid_list);
64 64
65int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 65int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
66{ 66{
67 struct nfs4_setclientid_res clid; 67 struct nfs4_setclientid_res clid = {
68 .clientid = clp->cl_clientid,
69 .confirm = clp->cl_confirm,
70 };
68 unsigned short port; 71 unsigned short port;
69 int status; 72 int status;
70 73
74 if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
75 goto do_confirm;
71 port = nfs_callback_tcpport; 76 port = nfs_callback_tcpport;
72 if (clp->cl_addr.ss_family == AF_INET6) 77 if (clp->cl_addr.ss_family == AF_INET6)
73 port = nfs_callback_tcpport6; 78 port = nfs_callback_tcpport6;
@@ -75,10 +80,14 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
75 status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid); 80 status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
76 if (status != 0) 81 if (status != 0)
77 goto out; 82 goto out;
83 clp->cl_clientid = clid.clientid;
84 clp->cl_confirm = clid.confirm;
85 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
86do_confirm:
78 status = nfs4_proc_setclientid_confirm(clp, &clid, cred); 87 status = nfs4_proc_setclientid_confirm(clp, &clid, cred);
79 if (status != 0) 88 if (status != 0)
80 goto out; 89 goto out;
81 clp->cl_clientid = clid.clientid; 90 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
82 nfs4_schedule_state_renewal(clp); 91 nfs4_schedule_state_renewal(clp);
83out: 92out:
84 return status; 93 return status;
@@ -230,13 +239,18 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
230{ 239{
231 int status; 240 int status;
232 241
242 if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
243 goto do_confirm;
233 nfs4_begin_drain_session(clp); 244 nfs4_begin_drain_session(clp);
234 status = nfs4_proc_exchange_id(clp, cred); 245 status = nfs4_proc_exchange_id(clp, cred);
235 if (status != 0) 246 if (status != 0)
236 goto out; 247 goto out;
248 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
249do_confirm:
237 status = nfs4_proc_create_session(clp); 250 status = nfs4_proc_create_session(clp);
238 if (status != 0) 251 if (status != 0)
239 goto out; 252 goto out;
253 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
240 nfs41_setup_state_renewal(clp); 254 nfs41_setup_state_renewal(clp);
241 nfs_mark_client_ready(clp, NFS_CS_READY); 255 nfs_mark_client_ready(clp, NFS_CS_READY);
242out: 256out:
@@ -1584,20 +1598,22 @@ static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
1584 */ 1598 */
1585static void nfs4_set_lease_expired(struct nfs_client *clp, int status) 1599static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1586{ 1600{
1587 if (nfs4_has_session(clp)) { 1601 switch (status) {
1588 switch (status) { 1602 case -NFS4ERR_CLID_INUSE:
1589 case -NFS4ERR_DELAY: 1603 case -NFS4ERR_STALE_CLIENTID:
1590 case -NFS4ERR_CLID_INUSE: 1604 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
1591 case -EAGAIN: 1605 break;
1592 break; 1606 case -NFS4ERR_DELAY:
1607 case -EAGAIN:
1608 ssleep(1);
1609 break;
1593 1610
1594 case -EKEYEXPIRED: 1611 case -EKEYEXPIRED:
1595 nfs4_warn_keyexpired(clp->cl_hostname); 1612 nfs4_warn_keyexpired(clp->cl_hostname);
1596 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1613 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1597 * in nfs4_exchange_id */ 1614 * in nfs4_exchange_id */
1598 default: 1615 default:
1599 return; 1616 return;
1600 }
1601 } 1617 }
1602 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1618 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1603} 1619}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 216cea5db0aa..87694ca86914 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -47,6 +47,7 @@ struct nfs_client {
47 47
48#ifdef CONFIG_NFS_V4 48#ifdef CONFIG_NFS_V4
49 u64 cl_clientid; /* constant */ 49 u64 cl_clientid; /* constant */
50 nfs4_verifier cl_confirm; /* Clientid verifier */
50 unsigned long cl_state; 51 unsigned long cl_state;
51 52
52 spinlock_t cl_lock; 53 spinlock_t cl_lock;