From 165641844bb9377d1fadb2d0ce6f58b6d5fc85c4 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 21 May 2012 22:45:33 -0400 Subject: [PATCH] --- yaml --- r: 308649 b: refs/heads/master c: 2c820d9a97f07b273b2c8a5960bd52b1b5864c68 h: refs/heads/master i: 308647: b9bfe2da1f165f4cfd774c8e7afecbe855fbe8ce v: v3 --- [refs] | 2 +- trunk/fs/nfs/nfs4_fs.h | 1 + trunk/fs/nfs/nfs4proc.c | 11 +++++++++-- trunk/fs/nfs/nfs4state.c | 13 +++++++++++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 21b525d8e6c7..027bde90c0c7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ce1c8fc12d99386737953dfeb7b531dfa3d18e5e +refs/heads/master: 2c820d9a97f07b273b2c8a5960bd52b1b5864c68 diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index 1526fdf47c4c..e6da02124c4e 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -24,6 +24,7 @@ enum nfs4_client_state { NFS4CLNT_RECALL_SLOT, NFS4CLNT_LEASE_CONFIRM, NFS4CLNT_SERVER_SCOPE_MISMATCH, + NFS4CLNT_PURGE_STATE, }; enum nfs4_session_state { diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index ab6b2e5c923e..81ccdbbb43e8 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -3908,8 +3908,15 @@ static void nfs4_construct_boot_verifier(struct nfs_client *clp, { __be32 verf[2]; - verf[0] = (__be32)clp->cl_boot_time.tv_sec; - verf[1] = (__be32)clp->cl_boot_time.tv_nsec; + if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) { + /* An impossible timestamp guarantees this value + * will never match a generated boot time. */ + verf[0] = 0; + verf[1] = (__be32)(NSEC_PER_SEC + 1); + } else { + verf[0] = (__be32)clp->cl_boot_time.tv_sec; + verf[1] = (__be32)clp->cl_boot_time.tv_nsec; + } memcpy(bootverf->data, verf, sizeof(bootverf->data)); } diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index f8c06dec6563..32cce4a276e8 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -1615,7 +1615,7 @@ void nfs41_handle_recall_slot(struct nfs_client *clp) static void nfs4_reset_all_state(struct nfs_client *clp) { if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { - clp->cl_boot_time = CURRENT_TIME; + set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state); nfs4_state_start_reclaim_nograce(clp); nfs4_schedule_state_manager(clp); } @@ -1631,7 +1631,6 @@ static void nfs41_handle_server_reboot(struct nfs_client *clp) static void nfs41_handle_state_revoked(struct nfs_client *clp) { - /* Temporary */ nfs4_reset_all_state(clp); } @@ -1652,6 +1651,10 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) { if (!flags) return; + + dprintk("%s: \"%s\" (client ID %llx) flags=0x%08x\n", + __func__, clp->cl_hostname, clp->cl_clientid, flags); + if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) nfs41_handle_server_reboot(clp); if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED | @@ -1762,6 +1765,12 @@ static void nfs4_state_manager(struct nfs_client *clp) /* Ensure exclusive access to NFSv4 state */ do { + if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) { + nfs4_reclaim_lease(clp); + clear_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state); + set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); + } + if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { /* We're going to have to re-establish a clientid */ status = nfs4_reclaim_lease(clp);