summaryrefslogtreecommitdiff
path: root/fs/nfs/delegation.c
AgeCommit message (Collapse)Author
2020-02-13NFSv4: Ensure the delegation cred is pinned when we call delegreturnTrond Myklebust
Ensure we don't release the delegation cred during the call to nfs4_proc_delegreturn(). Fixes: ee05f456772d ("NFSv4: Fix races between open and delegreturn") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-13NFSv4: Ensure the delegation is pinned in nfs_do_return_delegation()Trond Myklebust
The call to nfs_do_return_delegation() needs to be taken without any RCU locks. Add a refcount to make sure the delegation remains pinned in memory until we're done. Fixes: ee05f456772d ("NFSv4: Fix races between open and delegreturn") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-12NFSv4: Fix revalidation of dentries with delegationsTrond Myklebust
If a dentry was not initially looked up while we were holding a delegation, then we do still need to revalidate that it still holds the same name. If there are multiple hard links to the same file, then all the hard links need validation. Reported-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Benjamin Coddington <bcodding@redhat.com> Tested-by: Benjamin Coddington <bcodding@redhat.com> [Anna: Put nfs_unset_verifier_delegated() under CONFIG_NFS_V4] Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-03NFSv4: Limit the total number of cached delegationsTrond Myklebust
Delegations can be expensive to return, and can cause scalability issues for the server. Let's therefore try to limit the number of inactive delegations we hold. Once the number of delegations is above a certain threshold, start to return them on close. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-03NFSv4: Add accounting for the number of active delegations heldTrond Myklebust
In order to better manage our delegation caching, add a counter to track the number of active delegations. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-03NFSv4: Try to return the delegation immediately when marked for return on closeTrond Myklebust
Add a routine to return the delegation immediately upon close of the file if it was marked for return-on-close. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-03NFS: Clear NFS_DELEGATION_RETURN_IF_CLOSED when the delegation is returnedTrond Myklebust
If a delegation is marked as needing to be returned when the file is closed, then don't clear that marking until we're ready to return it. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2020-02-03NFSv4: nfs_inode_evict_delegation() should set NFS_DELEGATION_RETURNINGTrond Myklebust
In particular, the pnfs return-on-close code will check for that flag, so ensure we set it appropriately. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2019-11-03NFSv4: Handle NFS4ERR_OLD_STATEID in delegreturnTrond Myklebust
If the server returns NFS4ERR_OLD_STATEID in response to our delegreturn, we want to sync to the most recent seqid for the delegation stateid. However if we are already at the most recent, we have two possibilities: - an OPEN reply is still outstanding and will return a new seqid - an earlier OPEN reply was dropped on the floor due to a timeout. In the latter case, we may end up unable to complete the delegreturn, so we want to bump the seqid to a value greater than the cached value. While this may cause us to lose the delegation in the former case, it should now be safe to assume that the client will replay the OPEN if necessary in order to get a new valid stateid. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Fix races between open and delegreturnTrond Myklebust
If the server returns the same delegation in an open that we just used in a delegreturn, we need to ensure we don't apply that stateid if the delegreturn has freed it on the server. To do so, we ensure that we do not free the storage for the delegation until either it is replaced by a new one, or we throw the inode out of cache. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFS: nfs_inode_find_state_and_recover() fix stateid matchingTrond Myklebust
In nfs_inode_find_state_and_recover() we want to mark for recovery only those stateids that match or are older than the supplied stateid parameter. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Fix nfs4_inode_make_writeable()Trond Myklebust
Fix the checks in nfs4_inode_make_writeable() to ignore the case where we hold no delegations. Currently, in such a case, we automatically flush writes. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Don't reclaim delegations that have been returned or revokedTrond Myklebust
If the delegation has already been revoked, we want to avoid reclaiming it on reboot. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Ignore requests to return the delegation if it was revokedTrond Myklebust
If the delegation was revoked, or is already being returned, just clear the NFS_DELEGATION_RETURN and NFS_DELEGATION_RETURN_IF_CLOSED flags and keep going. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Revoke the delegation on success in nfs4_delegreturn_done()Trond Myklebust
If the delegation was successfully returned, then mark it as revoked. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Update the stateid seqid in nfs_revoke_delegation()Trond Myklebust
If we revoke a delegation, but the stateid's seqid is newer, then ensure we update the seqid when marking the delegation as revoked. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Clear the NFS_DELEGATION_REVOKED flag in nfs_update_inplace_delegation()Trond Myklebust
If the server sent us a new delegation stateid that is more recent than the one that got revoked, then clear the NFS_DELEGATION_REVOKED flag. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Hold the delegation spinlock when updating the seqidTrond Myklebust
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Don't remove the delegation from the super_list more than onceTrond Myklebust
Add a check to ensure that we haven't already removed the delegation from the inode after we take all the relevant locks. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFS: Rename nfs_inode_return_delegation_noreclaim()Trond Myklebust
Rename nfs_inode_return_delegation_noreclaim() to nfs_inode_evict_delegation(), which better describes what it does. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: fail nfs4_refresh_delegation_stateid() when the delegation was revokedTrond Myklebust
If the delegation was revoked, we don't want to retry the delegreturn. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-03NFSv4: Delegation recalls should not find revoked delegationsTrond Myklebust
If we're processsing a delegation recall, ignore the delegations that have already been revoked or returned. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-11-01NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid()Trond Myklebust
A typo in nfs4_refresh_delegation_stateid() means we're leaking an RCU lock, and always returning a value of 'false'. As the function description states, we were always supposed to return 'true' if a matching delegation was found. Fixes: 12f275cdd163 ("NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID.") Cc: stable@vger.kernel.org # v4.15+ Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2019-11-01NFSv4: Don't allow a cached open with a revoked delegationTrond Myklebust
If the delegation is marked as being revoked, we must not use it for cached opens. Fixes: 869f9dfa4d6d ("NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2019-08-04NFSv4.1: Only reap expired delegationsTrond Myklebust
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>
2019-08-04NFSv4: Fix delegation state recoveryTrond Myklebust
Once we clear the NFS_DELEGATED_STATE flag, we're telling nfs_delegation_claim_opens() that we're done recovering all open state for that stateid, so we really need to ensure that we test for all open modes that are currently cached and recover them before exiting nfs4_open_delegation_recall(). Fixes: 24311f884189d ("NFSv4: Recovery of recalled read delegations...") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Cc: stable@vger.kernel.org # v4.3+
2019-05-21treewide: Add SPDX license identifier for missed filesThomas Gleixner
Add SPDX license identifiers to all files which: - Have no license information of any form - Have EXPORT_.*_SYMBOL_GPL inside which was used in the initial scan/conversion to ignore the file These files fall under the project license, GPL v2 only. The resulting SPDX license identifier is: GPL-2.0-only Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-09NFSv4: don't mark all open state for recovery when handling recallable state ↵Scott Mayhew
revoked flag Only delegations and layouts can be recalled, so it shouldn't be necessary to recover all opens when handling the status bit SEQ4_STATUS_RECALLABLE_STATE_REVOKED. We'll still wind up calling nfs41_open_expired() when a TEST_STATEID returns NFS4ERR_DELEG_REVOKED. Signed-off-by: Scott Mayhew <smayhew@redhat.com> Reviewed-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2019-02-21NFS: Fix a soft lockup in the delegation recovery codeTrond Myklebust
Fix a soft lockup when NFS client delegation recovery is attempted but the inode is in the process of being freed. When the igrab(inode) call fails, and we have to restart the recovery process, we need to ensure that we won't attempt to recover the same delegation again. Fixes: 45870d6909d5a ("NFSv4.1: Test delegation stateids when server...") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-02-20NFS: Fix up documentation warningsTrond Myklebust
Fix up some compiler warnings about function parameters, etc not being correctly described or formatted. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-12-19NFS/NFSD/SUNRPC: replace generic creds with 'struct cred'.NeilBrown
SUNRPC has two sorts of credentials, both of which appear as "struct rpc_cred". There are "generic credentials" which are supplied by clients such as NFS and passed in 'struct rpc_message' to indicate which user should be used to authorize the request, and there are low-level credentials such as AUTH_NULL, AUTH_UNIX, AUTH_GSS which describe the credential to be sent over the wires. This patch replaces all the generic credentials by 'struct cred' pointers - the credential structure used throughout Linux. For machine credentials, there is a special 'struct cred *' pointer which is statically allocated and recognized where needed as having a special meaning. A look-up of a low-level cred will map this to a machine credential. Signed-off-by: NeilBrown <neilb@suse.com> Acked-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2018-11-13NFSv4: Fix an Oops during delegation callbacksTrond Myklebust
If the server sends a CB_GETATTR or a CB_RECALL while the filesystem is being unmounted, then we can Oops when releasing the inode in nfs4_callback_getattr() and nfs4_callback_recall(). Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-10-05NFSv4.x: fix lock recovery during delegation recallOlga Kornievskaia
Running "./nfstest_delegation --runtest recall26" uncovers that client doesn't recover the lock when we have an appending open, where the initial open got a write delegation. Instead of checking for the passed in open context against the file lock's open context. Check that the state is the same. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-09-30NFS: Convert lookups of the open context to RCUTrond Myklebust
Reduce contention on the inode->i_lock by ensuring that we use RCU when looking up the NFS open context. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-06-14NFS: Fix an rcu deadlock in nfs_delegation_find_inode()Anna Schumaker
I was able to reproduce this pretty regularily using xfstests generic/013 on NFS v4.0. Reported-by: Ross Zwisler <Ross.Zwisler@linux.intel.com> Fixes: 6c342655022d (NFSv4: Return NFS4ERR_DELAY when a delegation recall fails due to igrab()) Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-06-08NFSv4: Return NFS4ERR_DELAY when a delegation recall fails due to igrab()Trond Myklebust
If the attempt to recall the delegation fails because the inode is in the process of being evicted from cache, then use NFS4ERR_DELAY to ask the server to retry later. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-06-04NFSv4: Ensure the inode is clean when we set a delegationTrond Myklebust
If there are attributes that are still invalid when we set a delegation, then we need to set the NFS_INO_REVAL_FORCED flag. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-05-31NFS: Avoid quadratic search when freeing delegations.NeilBrown
There are three places that walk all delegation for an nfs_client and restart whenever they find something interesting - potentially resulting in a quadratic search: If there are 10,000 uninteresting delegations followed by 10,000 interesting one, then the code skips over 100,000,000 delegations, which can take a noticeable amount of time. Of these nfs_delegation_reap_unclaimed() and nfs_reap_expired_delegations() are only called during unusual events: a server reboots or reports expired delegations, probably due to a network partition. Optimizing these is not particularly important. The third, nfs_client_return_marked_delegations(), is called periodically via nfs_expire_unreferenced_delegations(). It could cause periodic problems on a busy server. New delegations are added to the end of the list, so if there are 10,000 open files with delegations, and 10,000 more recently opened files that received delegations but are now closed, then nfs_client_return_marked_delegations() can take seconds to skip over the 10,000 open files 10,000 times. That is a waste of time. The avoid this waste a place-holder (an inode) is kept when locks are dropped, so that the place can usually be found again after taking rcu_readlock(). This place holder ensure that we find the right starting point in the list of nfs_servers, and makes is probable that we find the right starting point in the list of delegations. We might need to occasionally restart at the head of that list. It might be possible that the place_holder inode could lose its delegation separately, and then get a new one using the same (freed and then reallocated) 'struct nfs_delegation'. Were this to happen, the new delegation would be at the end of the list and we would miss returning some other delegations. This would have the effect of unnecessarily delaying the return of some unused delegations until the next time this function is called - typically 90 seconds later. As this is not a correctness issue and is vanishingly unlikely to happen, it does not seem worth addressing. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-05-31NFS: use cond_resched() when restarting walk of delegation list.NeilBrown
In three places we walk the list of delegations for an nfs_client until an interesting one is found, then we act of that delegation and restart the walk. New delegations are added to the end of a list and the interesting delegations are usually old, so in many case we won't repeat a long walk over and over again, but it is possible - particularly if the first server in the list has a large number of uninteresting delegations. In each cache the work done on interesting delegations will often complete without sleeping, so this could loop many times without giving up the CPU. So add a cond_resched() at an appropriate point to avoid hogging the CPU for too long. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-05-31NFS: slight optimization for walking list for delegationsNeilBrown
There are 3 places where we walk the list of delegations for an nfs_client. In each case there are two nested loops, one for nfs_servers and one for nfs_delegations. When we find an interesting delegation we try to get an active reference to the server. If that fails, it is pointless to continue to look at the other delegation for the server as we will never be able to get an active reference. So instead of continuing in the inner loop, break out and continue in the outer loop. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-04-10NFSv4: Fix the nfs_inode_set_delegation() argumentsTrond Myklebust
Neither nfs_inode_set_delegation() nor nfs_inode_reclaim_delegation() are generic code. They have no business delving into NFSv4 OPEN xdr structures, so let's replace the "struct nfs_openres" parameter. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2018-04-10NFSv4: Don't return the delegation when not needed by NFSv4.x (x>0)Trond Myklebust
Starting with NFSv4.1, the server is able to deduce the client id from the SEQUENCE op which means it can always figure out whether or not the client is holding a delegation on a file that is being changed. For that reason, RFC5661 does not require a delegation to be unconditionally recalled on operations such as SETATTR, RENAME, or REMOVE. Note that for now, we continue to return READ delegations since that is still expected by the Linux knfsd server. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2018-01-29nfs: convert to new i_version APIJeff Layton
For NFS, we just use the "raw" API since the i_version is mostly managed by the server. The exception there is when the client holds a write delegation, but we only need to bump it once there anyway to handle CB_GETATTR. Tested-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Jeff Layton <jlayton@redhat.com>
2017-11-17NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID.Trond Myklebust
If we're racing with an OPEN, then retry the operation instead of declaring it a success. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> [Andrew W Elble: Fix a typo in nfs4_refresh_open_stateid] Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2017-08-15NFS: Use an atomic_long_t to count the number of requestsTrond Myklebust
Rather than forcing us to take the inode->i_lock just in order to bump the number. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2016-12-01NFSv4: Optimise away forced revalidation when we know the attributes are OKTrond Myklebust
The NFS_INO_REVAL_FORCED flag needs to be set if we just got a delegation, and we see that there might still be some ambiguity as to whether or not our attribute or data cache are valid. In practice, this means that a call to nfs_check_inode_attributes() will have noticed a discrepancy between cached attributes and measured ones, so let's move the setting of NFS_INO_REVAL_FORCED to there. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2016-09-27NFS: Always call nfs_inode_find_state_and_recover() when revoking a delegationTrond Myklebust
Don't rely on nfs_inode_detach_delegation() succeeding. That can race... Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Tested-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2016-09-27NFSv4: Fix a race in nfs_inode_reclaim_delegation()Trond Myklebust
If we race with a delegreturn before taking the spin lock, we currently end up dropping the delegation stateid. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Tested-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2016-09-27NFSv4: nfs_inode_find_state_and_recover() should check all stateidsTrond Myklebust
Modify the helper nfs_inode_find_state_and_recover() so that it can check all open/lock/delegation state trackers on that inode for whether or not they need are affected by a revoked stateid error. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Tested-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
2016-09-27NFSv4: Ensure we don't re-test revoked and freed stateidsTrond Myklebust
This fixes a potential infinite loop in nfs_reap_expired_delegations. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Tested-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>