diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-07-26 14:40:53 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-08-29 08:30:13 +0200 |
commit | 55a76b7b9a5c987996fbc3464dd6552b98e0edfa (patch) | |
tree | f04d864409bf546ef61b2c99a308ceb91be63ec7 | |
parent | 00cfd19b4aab5fcb4be629e43224501d9ef7465c (diff) | |
download | linux-stable-55a76b7b9a5c987996fbc3464dd6552b98e0edfa.tar.gz linux-stable-55a76b7b9a5c987996fbc3464dd6552b98e0edfa.tar.bz2 linux-stable-55a76b7b9a5c987996fbc3464dd6552b98e0edfa.zip |
NFSv4.1: Only reap expired delegations
[ Upstream commit ad11408970df79d5f481aa9964e91f183133424c ]
Fix nfs_reap_expired_delegations() to ensure that we only reap delegations
that are actually expired, rather than triggering on random errors.
Fixes: 45870d6909d5a ("NFSv4.1: Test delegation stateids when server...")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | fs/nfs/delegation.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 0af854cce8ff..071b90a45933 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -1046,6 +1046,22 @@ void nfs_test_expired_all_delegations(struct nfs_client *clp) nfs4_schedule_state_manager(clp); } +static void +nfs_delegation_test_free_expired(struct inode *inode, + nfs4_stateid *stateid, + const struct cred *cred) +{ + struct nfs_server *server = NFS_SERVER(inode); + const struct nfs4_minor_version_ops *ops = server->nfs_client->cl_mvops; + int status; + + if (!cred) + return; + status = ops->test_and_free_expired(server, stateid, cred); + if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) + nfs_remove_bad_delegation(inode, stateid); +} + /** * nfs_reap_expired_delegations - reap expired delegations * @clp: nfs_client to process @@ -1057,7 +1073,6 @@ void nfs_test_expired_all_delegations(struct nfs_client *clp) */ void nfs_reap_expired_delegations(struct nfs_client *clp) { - const struct nfs4_minor_version_ops *ops = clp->cl_mvops; struct nfs_delegation *delegation; struct nfs_server *server; struct inode *inode; @@ -1088,11 +1103,7 @@ restart: nfs4_stateid_copy(&stateid, &delegation->stateid); clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags); rcu_read_unlock(); - if (cred != NULL && - ops->test_and_free_expired(server, &stateid, cred) < 0) { - nfs_revoke_delegation(inode, &stateid); - nfs_inode_find_state_and_recover(inode, &stateid); - } + nfs_delegation_test_free_expired(inode, &stateid, cred); put_cred(cred); if (nfs4_server_rebooted(clp)) { nfs_inode_mark_test_expired_delegation(server,inode); |