diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-25 15:00:06 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-25 16:17:13 -0400 |
commit | 2a6ee6aa2f6dfc47fce8380ec9e31601c96a693e (patch) | |
tree | c1dd3edf1cd6f53c62d352d921ddfb96ad2af221 /fs | |
parent | bbafffd293e47f4cd5f0ae8b91d7d5767b242a5e (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.c | 99 |
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 | */ | ||
1580 | static 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 | |||
1577 | static int nfs4_reclaim_lease(struct nfs_client *clp) | 1613 | static 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 | */ | ||
1757 | static 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 | |||
1780 | static void nfs4_state_manager(struct nfs_client *clp) | 1785 | static 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, |