aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4_fs.h1
-rw-r--r--fs/nfs/nfs4proc.c11
-rw-r--r--fs/nfs/nfs4state.c13
3 files changed, 21 insertions, 4 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 1526fdf47c4c..e6da02124c4e 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -24,6 +24,7 @@ enum nfs4_client_state {
24 NFS4CLNT_RECALL_SLOT, 24 NFS4CLNT_RECALL_SLOT,
25 NFS4CLNT_LEASE_CONFIRM, 25 NFS4CLNT_LEASE_CONFIRM,
26 NFS4CLNT_SERVER_SCOPE_MISMATCH, 26 NFS4CLNT_SERVER_SCOPE_MISMATCH,
27 NFS4CLNT_PURGE_STATE,
27}; 28};
28 29
29enum nfs4_session_state { 30enum nfs4_session_state {
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ab6b2e5c923e..81ccdbbb43e8 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3908,8 +3908,15 @@ static void nfs4_construct_boot_verifier(struct nfs_client *clp,
3908{ 3908{
3909 __be32 verf[2]; 3909 __be32 verf[2];
3910 3910
3911 verf[0] = (__be32)clp->cl_boot_time.tv_sec; 3911 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
3912 verf[1] = (__be32)clp->cl_boot_time.tv_nsec; 3912 /* An impossible timestamp guarantees this value
3913 * will never match a generated boot time. */
3914 verf[0] = 0;
3915 verf[1] = (__be32)(NSEC_PER_SEC + 1);
3916 } else {
3917 verf[0] = (__be32)clp->cl_boot_time.tv_sec;
3918 verf[1] = (__be32)clp->cl_boot_time.tv_nsec;
3919 }
3913 memcpy(bootverf->data, verf, sizeof(bootverf->data)); 3920 memcpy(bootverf->data, verf, sizeof(bootverf->data));
3914} 3921}
3915 3922
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index f8c06dec6563..32cce4a276e8 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1615,7 +1615,7 @@ void nfs41_handle_recall_slot(struct nfs_client *clp)
1615static void nfs4_reset_all_state(struct nfs_client *clp) 1615static void nfs4_reset_all_state(struct nfs_client *clp)
1616{ 1616{
1617 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { 1617 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1618 clp->cl_boot_time = CURRENT_TIME; 1618 set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
1619 nfs4_state_start_reclaim_nograce(clp); 1619 nfs4_state_start_reclaim_nograce(clp);
1620 nfs4_schedule_state_manager(clp); 1620 nfs4_schedule_state_manager(clp);
1621 } 1621 }
@@ -1631,7 +1631,6 @@ static void nfs41_handle_server_reboot(struct nfs_client *clp)
1631 1631
1632static void nfs41_handle_state_revoked(struct nfs_client *clp) 1632static void nfs41_handle_state_revoked(struct nfs_client *clp)
1633{ 1633{
1634 /* Temporary */
1635 nfs4_reset_all_state(clp); 1634 nfs4_reset_all_state(clp);
1636} 1635}
1637 1636
@@ -1652,6 +1651,10 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
1652{ 1651{
1653 if (!flags) 1652 if (!flags)
1654 return; 1653 return;
1654
1655 dprintk("%s: \"%s\" (client ID %llx) flags=0x%08x\n",
1656 __func__, clp->cl_hostname, clp->cl_clientid, flags);
1657
1655 if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) 1658 if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
1656 nfs41_handle_server_reboot(clp); 1659 nfs41_handle_server_reboot(clp);
1657 if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED | 1660 if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
@@ -1762,6 +1765,12 @@ static void nfs4_state_manager(struct nfs_client *clp)
1762 1765
1763 /* Ensure exclusive access to NFSv4 state */ 1766 /* Ensure exclusive access to NFSv4 state */
1764 do { 1767 do {
1768 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
1769 nfs4_reclaim_lease(clp);
1770 clear_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
1771 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1772 }
1773
1765 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1774 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
1766 /* We're going to have to re-establish a clientid */ 1775 /* We're going to have to re-establish a clientid */
1767 status = nfs4_reclaim_lease(clp); 1776 status = nfs4_reclaim_lease(clp);