aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-25 15:00:06 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-25 16:17:13 -0400
commit2a6ee6aa2f6dfc47fce8380ec9e31601c96a693e (patch)
treec1dd3edf1cd6f53c62d352d921ddfb96ad2af221 /fs
parentbbafffd293e47f4cd5f0ae8b91d7d5767b242a5e (diff)
NFSv4: Clean up the error handling for nfs4_reclaim_lease
Try to consolidate the error handling for nfs4_reclaim_lease into a single function instead of doing a bit here, and a bit there... Also ensure that NFS4CLNT_PURGE_STATE handles errors correctly. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4state.c99
1 files changed, 50 insertions, 49 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 03fa802b5529..758b9a8a54b3 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1574,26 +1574,57 @@ out:
1574 return nfs4_recovery_handle_error(clp, status); 1574 return nfs4_recovery_handle_error(clp, status);
1575} 1575}
1576 1576
1577/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
1578 * on EXCHANGE_ID for v4.1
1579 */
1580static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
1581{
1582 switch (status) {
1583 case -NFS4ERR_CLID_INUSE:
1584 case -NFS4ERR_STALE_CLIENTID:
1585 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
1586 break;
1587 case -EACCES:
1588 if (clp->cl_machine_cred == NULL)
1589 return -EACCES;
1590 /* Handle case where the user hasn't set up machine creds */
1591 nfs4_clear_machine_cred(clp);
1592 case -NFS4ERR_DELAY:
1593 case -ETIMEDOUT:
1594 case -EAGAIN:
1595 ssleep(1);
1596 break;
1597
1598 case -NFS4ERR_MINOR_VERS_MISMATCH:
1599 if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
1600 nfs_mark_client_ready(clp, -EPROTONOSUPPORT);
1601 return -EPROTONOSUPPORT;
1602 case -EKEYEXPIRED:
1603 nfs4_warn_keyexpired(clp->cl_hostname);
1604 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1605 * in nfs4_exchange_id */
1606 default:
1607 return status;
1608 }
1609 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1610 return 0;
1611}
1612
1577static int nfs4_reclaim_lease(struct nfs_client *clp) 1613static int nfs4_reclaim_lease(struct nfs_client *clp)
1578{ 1614{
1579 struct rpc_cred *cred; 1615 struct rpc_cred *cred;
1580 const struct nfs4_state_recovery_ops *ops = 1616 const struct nfs4_state_recovery_ops *ops =
1581 clp->cl_mvops->reboot_recovery_ops; 1617 clp->cl_mvops->reboot_recovery_ops;
1582 int status = -ENOENT; 1618 int status;
1583 1619
1584 cred = ops->get_clid_cred(clp); 1620 cred = ops->get_clid_cred(clp);
1585 if (cred != NULL) { 1621 if (cred == NULL)
1586 status = ops->establish_clid(clp, cred); 1622 return -ENOENT;
1587 put_rpccred(cred); 1623 status = ops->establish_clid(clp, cred);
1588 /* Handle case where the user hasn't set up machine creds */ 1624 put_rpccred(cred);
1589 if (status == -EACCES && cred == clp->cl_machine_cred) { 1625 if (status != 0)
1590 nfs4_clear_machine_cred(clp); 1626 return nfs4_handle_reclaim_lease_error(clp, status);
1591 status = -EAGAIN; 1627 return 0;
1592 }
1593 if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
1594 status = -EPROTONOSUPPORT;
1595 }
1596 return status;
1597} 1628}
1598 1629
1599#ifdef CONFIG_NFS_V4_1 1630#ifdef CONFIG_NFS_V4_1
@@ -1751,32 +1782,6 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
1751} 1782}
1752#endif /* CONFIG_NFS_V4_1 */ 1783#endif /* CONFIG_NFS_V4_1 */
1753 1784
1754/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
1755 * on EXCHANGE_ID for v4.1
1756 */
1757static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1758{
1759 switch (status) {
1760 case -NFS4ERR_CLID_INUSE:
1761 case -NFS4ERR_STALE_CLIENTID:
1762 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
1763 break;
1764 case -NFS4ERR_DELAY:
1765 case -ETIMEDOUT:
1766 case -EAGAIN:
1767 ssleep(1);
1768 break;
1769
1770 case -EKEYEXPIRED:
1771 nfs4_warn_keyexpired(clp->cl_hostname);
1772 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1773 * in nfs4_exchange_id */
1774 default:
1775 return;
1776 }
1777 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1778}
1779
1780static void nfs4_state_manager(struct nfs_client *clp) 1785static void nfs4_state_manager(struct nfs_client *clp)
1781{ 1786{
1782 int status = 0; 1787 int status = 0;
@@ -1784,7 +1789,9 @@ static void nfs4_state_manager(struct nfs_client *clp)
1784 /* Ensure exclusive access to NFSv4 state */ 1789 /* Ensure exclusive access to NFSv4 state */
1785 do { 1790 do {
1786 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) { 1791 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
1787 nfs4_reclaim_lease(clp); 1792 status = nfs4_reclaim_lease(clp);
1793 if (status < 0)
1794 goto out_error;
1788 clear_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state); 1795 clear_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
1789 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1796 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1790 } 1797 }
@@ -1792,16 +1799,10 @@ static void nfs4_state_manager(struct nfs_client *clp)
1792 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1799 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
1793 /* We're going to have to re-establish a clientid */ 1800 /* We're going to have to re-establish a clientid */
1794 status = nfs4_reclaim_lease(clp); 1801 status = nfs4_reclaim_lease(clp);
1795 if (status) { 1802 if (status < 0)
1796 nfs4_set_lease_expired(clp, status);
1797 if (test_bit(NFS4CLNT_LEASE_EXPIRED,
1798 &clp->cl_state))
1799 continue;
1800 if (clp->cl_cons_state ==
1801 NFS_CS_SESSION_INITING)
1802 nfs_mark_client_ready(clp, status);
1803 goto out_error; 1803 goto out_error;
1804 } 1804 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
1805 continue;
1805 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); 1806 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1806 1807
1807 if (test_and_clear_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, 1808 if (test_and_clear_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH,