aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-07-11 16:30:05 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-07-16 14:48:53 -0400
commiteb64cf964d453f8b559a8c0c2625952dbbcb5838 (patch)
treeb6ac6d9cfdee8d8ae1710d6f2fb25520d7d2a576 /fs/nfs/nfs4proc.c
parent89af2739589365bf0dd2023c6a076b22ccd530f9 (diff)
NFS: State reclaim clears OPEN and LOCK state
The "state->flags & flags" test in nfs41_check_expired_stateid() allows the state manager to squelch a TEST_STATEID operation when it is known for sure that a state ID is no longer valid. If the lease was purged, for example, the client already knows that state ID is now defunct. But open recovery is still needed for that inode. To force a call to nfs4_open_expired(), change the default return value for nfs41_check_expired_stateid() to force open recovery, and the default return value for nfs41_check_locks() to force lock recovery, if the requested flags are clear. Fix suggested by Bryan Schumaker. Also, the presence of a delegation state ID must not prevent normal open recovery. The delegation state ID must be cleared if it was revoked, but once cleared I don't think it's presence or absence has any bearing on whether open recovery is still needed. So the logic is adjusted to ignore the TEST_STATEID result for the delegation state ID. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index afd61d72837d..d1c1016cd505 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1758,8 +1758,8 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
1758#if defined(CONFIG_NFS_V4_1) 1758#if defined(CONFIG_NFS_V4_1)
1759static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *stateid, unsigned int flags) 1759static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *stateid, unsigned int flags)
1760{ 1760{
1761 int status = NFS_OK;
1762 struct nfs_server *server = NFS_SERVER(state->inode); 1761 struct nfs_server *server = NFS_SERVER(state->inode);
1762 int status = -NFS4ERR_BAD_STATEID;
1763 1763
1764 if (state->flags & flags) { 1764 if (state->flags & flags) {
1765 status = nfs41_test_stateid(server, stateid); 1765 status = nfs41_test_stateid(server, stateid);
@@ -1774,16 +1774,17 @@ static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *s
1774 1774
1775static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) 1775static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
1776{ 1776{
1777 int deleg_status, open_status;
1778 int deleg_flags = 1 << NFS_DELEGATED_STATE; 1777 int deleg_flags = 1 << NFS_DELEGATED_STATE;
1779 int open_flags = (1 << NFS_O_RDONLY_STATE) | (1 << NFS_O_WRONLY_STATE) | (1 << NFS_O_RDWR_STATE); 1778 int open_flags = (1 << NFS_O_RDONLY_STATE) | (1 << NFS_O_WRONLY_STATE) | (1 << NFS_O_RDWR_STATE);
1779 int status;
1780 1780
1781 deleg_status = nfs41_check_expired_stateid(state, &state->stateid, deleg_flags); 1781 nfs41_check_expired_stateid(state, &state->stateid, deleg_flags);
1782 open_status = nfs41_check_expired_stateid(state, &state->open_stateid, open_flags); 1782 status = nfs41_check_expired_stateid(state, &state->open_stateid,
1783 open_flags);
1783 1784
1784 if ((deleg_status == NFS_OK) && (open_status == NFS_OK)) 1785 if (status != NFS_OK)
1785 return NFS_OK; 1786 status = nfs4_open_expired(sp, state);
1786 return nfs4_open_expired(sp, state); 1787 return status;
1787} 1788}
1788#endif 1789#endif
1789 1790
@@ -4690,7 +4691,7 @@ out:
4690#if defined(CONFIG_NFS_V4_1) 4691#if defined(CONFIG_NFS_V4_1)
4691static int nfs41_check_expired_locks(struct nfs4_state *state) 4692static int nfs41_check_expired_locks(struct nfs4_state *state)
4692{ 4693{
4693 int status, ret = NFS_OK; 4694 int status, ret = -NFS4ERR_BAD_STATEID;
4694 struct nfs4_lock_state *lsp; 4695 struct nfs4_lock_state *lsp;
4695 struct nfs_server *server = NFS_SERVER(state->inode); 4696 struct nfs_server *server = NFS_SERVER(state->inode);
4696 4697
@@ -4716,9 +4717,9 @@ static int nfs41_lock_expired(struct nfs4_state *state, struct file_lock *reques
4716 4717
4717 if (test_bit(LK_STATE_IN_USE, &state->flags)) 4718 if (test_bit(LK_STATE_IN_USE, &state->flags))
4718 status = nfs41_check_expired_locks(state); 4719 status = nfs41_check_expired_locks(state);
4719 if (status == NFS_OK) 4720 if (status != NFS_OK)
4720 return status; 4721 status = nfs4_lock_expired(state, request);
4721 return nfs4_lock_expired(state, request); 4722 return status;
4722} 4723}
4723#endif 4724#endif
4724 4725