aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a6804f704d9..036f5adc9e1 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,23 @@ 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 -ETIMEDOUT:
1608 case -EAGAIN:
1609 ssleep(1);
1610 break;
1593 1611
1594 case -EKEYEXPIRED: 1612 case -EKEYEXPIRED:
1595 nfs4_warn_keyexpired(clp->cl_hostname); 1613 nfs4_warn_keyexpired(clp->cl_hostname);
1596 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1614 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1597 * in nfs4_exchange_id */ 1615 * in nfs4_exchange_id */
1598 default: 1616 default:
1599 return; 1617 return;
1600 }
1601 } 1618 }
1602 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1619 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1603} 1620}
@@ -1607,7 +1624,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1607 int status = 0; 1624 int status = 0;
1608 1625
1609 /* Ensure exclusive access to NFSv4 state */ 1626 /* Ensure exclusive access to NFSv4 state */
1610 for(;;) { 1627 do {
1611 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1628 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
1612 /* We're going to have to re-establish a clientid */ 1629 /* We're going to have to re-establish a clientid */
1613 status = nfs4_reclaim_lease(clp); 1630 status = nfs4_reclaim_lease(clp);
@@ -1691,7 +1708,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1691 break; 1708 break;
1692 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) 1709 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
1693 break; 1710 break;
1694 } 1711 } while (atomic_read(&clp->cl_count) > 1);
1695 return; 1712 return;
1696out_error: 1713out_error:
1697 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" 1714 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"