aboutsummaryrefslogtreecommitdiff
path: root/fs/nfsd
AgeCommit message (Collapse)AuthorFilesLines
2014-08-01nfsd: Ensure that the laundromat unhashes the client before releasing locksTrond Myklebust1-1/+3
If we leave the client on the confirmed/unconfirmed tables, and leave the sessions visible on the sessionid_hashtbl, then someone might find them before we've had a chance to destroy them. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-08-01nfsd: Ensure struct nfs4_client is unhashed before we try to destroy itTrond Myklebust1-10/+33
When we remove the client_mutex protection, we will need to ensure that it can't be found by other threads while we're destroying it. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-08-01nfsd4: fix out of date commentJ. Bruce Fields1-1/+1
Signed-off-by: J. Bruce Fields <[email protected]>
2014-08-01NFSD: Decrease nfsd_users in nfsd_startup_generic failKinglong Mee1-1/+4
A memory allocation failure could cause nfsd_startup_generic to fail, in which case nfsd_users wouldn't be incorrectly left elevated. After nfsd restarts nfsd_startup_generic will then succeed without doing anything--the first consequence is likely nfs4_start_net finding a bad laundry_wq and crashing. Signed-off-by: Kinglong Mee <[email protected]> Fixes: 4539f14981ce "nfsd: replace boolean nfsd_up flag by users counter" Cc: [email protected] Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: rename unhash_generic_stateid to unhash_ol_stateidJeff Layton1-3/+3
...to better match other functions that deal with open/lock stateids. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: don't thrash the cl_lock while freeing an open stateidJeff Layton1-15/+19
When we remove the client_mutex, we'll have a potential race between FREE_STATEID and CLOSE. The root of the problem is that we are walking the st_locks list, dropping the spinlock and then trying to release the persistent reference to the lockstateid. In between, a FREE_STATEID call can come along and take the lock, find the stateid and then try to put the reference. That leads to a double put. Fix this by not releasing the cl_lock in order to release each lock stateid. Use put_generic_stateid_locked to unhash them and gather them onto a list, and free_ol_stateid_reaplist to free any that end up on the list. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: reduce cl_lock thrashing in release_openownerJeff Layton1-33/+63
Releasing an openowner is a bit inefficient as it can potentially thrash the cl_lock if you have a lot of stateids attached to it. Once we remove the client_mutex, it'll also potentially be dangerous to do this. Add some functions to make it easier to defer the part of putting a generic stateid reference that needs to be done outside the cl_lock while doing the parts that must be done while holding it under a single lock. First we unhash each open stateid. Then we call put_generic_stateid_locked which will put the reference to an nfs4_ol_stateid. If it turns out to be the last reference, it'll go ahead and remove the stid from the IDR tree and put it onto the reaplist using the st_locks list_head. Then, after dropping the lock we'll call free_ol_stateid_reaplist to walk the list of stateids that are fully unhashed and ready to be freed, and free each of them. This function can sleep, so it must be done outside any spinlocks. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: close potential race in nfsd4_free_stateidJeff Layton1-12/+9
Once we remove the client_mutex, it'll be possible for the sc_type of a lock stateid to change after it's found and checked, but before we can go to destroy it. If that happens, we can end up putting the persistent reference to the stateid more than once, and unhash it more than once. Fix this by unhashing the lock stateid prior to dropping the cl_lock but after finding it. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: optimize destroy_lockowner cl_lock thrashingJeff Layton1-17/+34
Reduce the cl_lock trashing in destroy_lockowner. Unhash all of the lockstateids on the lockowner's list. Put the reference under the lock and see if it was the last one. If so, then add it to a private list to be destroyed after we drop the lock. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: add locking to stateowner releaseJeff Layton1-9/+6
Once we remove the client_mutex, we'll need to properly protect the stateowner reference counts using the cl_lock. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: clean up and reorganize release_lockownerJeff Layton1-31/+18
Do more within the main loop, and simplify the function a bit. Also, there's no need to take a stateowner reference unless we're going to call release_lockowner. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Move the open owner hash table into struct nfs4_clientTrond Myklebust3-103/+86
Preparation for removing the client_mutex. Convert the open owner hash table into a per-client table and protect it using the nfs4_client->cl_lock spin lock. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Protect adding/removing lock owners using client_lockTrond Myklebust1-8/+61
Once we remove client mutex protection, we'll need to ensure that stateowner lookup and creation are atomic between concurrent compounds. Ensure that alloc_init_lock_stateowner checks the hashtable under the client_lock before adding a new element. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Protect adding/removing open state owners using client_lockTrond Myklebust1-38/+80
Once we remove client mutex protection, we'll need to ensure that stateowner lookup and creation are atomic between concurrent compounds. Ensure that alloc_init_open_stateowner checks the hashtable under the client_lock before adding a new element. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: don't allow CLOSE to proceed until refcount on stateid dropsJeff Layton1-1/+20
Once we remove client_mutex protection, it'll be possible to have an in-flight operation using an openstateid when a CLOSE call comes in. If that happens, we can't just put the sc_file reference and clear its pointer without risking an oops. Fix this by ensuring that v4.0 CLOSE operations wait for the refcount to drop before proceeding to do so. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: make openstateids hold references to their openownersJeff Layton2-42/+32
Change it so that only openstateids hold persistent references to openowners. References can still be held by compounds in progress. With this, we can get rid of NFS4_OO_NEW. It's possible that we will create a new openowner in the process of doing the open, but something later fails. In the meantime, another task could find that openowner and start using it on a successful open. If that occurs we don't necessarily want to tear it down, just put the reference that the failing compound holds. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: clean up refcounting for lockownersJeff Layton1-22/+7
Ensure that lockowner references are only held by lockstateids and operations that are in-progress. With this, we can get rid of release_lockowner_if_empty, which will be racy once we remove client_mutex protection. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Make lock stateid take a reference to the lockownerTrond Myklebust1-0/+3
A necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: add an operation for unhashing a stateownerJeff Layton2-12/+38
Allow stateowners to be unhashed and destroyed when the last reference is put. The unhashing must be idempotent. In a future patch, we'll add some locking around it, but for now it's only protected by the client_mutex. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: clean up lockowner refcounting when finding themJeff Layton1-12/+33
Ensure that when finding or creating a lockowner, that we get a reference to it. For now, we also take an extra reference when a lockowner is created that can be put when release_lockowner is called, but we'll remove that in a later patch once we change how references are held. Since we no longer destroy lockowners in the event of an error in nfsd4_lock, we must change how the seqid gets bumped in the lk_is_new case. Instead of doing so on creation, do it manually in nfsd4_lock. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add a mutex to protect the NFSv4.0 open owner replay cacheJeff Layton5-26/+41
We don't want to rely on the client_mutex for protection in the case of NFSv4 open owners. Instead, we add a mutex that will only be taken for NFSv4.0 state mutating operations, and that will be released once the entire compound is done. Also, ensure that nfsd4_cstate_assign_replay/nfsd4_cstate_clear_replay take a reference to the stateowner when they are using it for NFSv4.0 open and lock replay caching. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add reference counting to state ownersJeff Layton2-21/+50
The way stateowners are managed today is somewhat awkward. They need to be explicitly destroyed, even though the stateids reference them. This will be particularly problematic when we remove the client_mutex. We may create a new stateowner and attempt to open a file or set a lock, and have that fail. In the meantime, another RPC may come in that uses that same stateowner and succeed. We can't have the first task tearing down the stateowner in that situation. To fix this, we need to change how stateowners are tracked altogether. Refcount them and only destroy them once all stateids that reference them have been destroyed. This patch starts by adding the refcounting necessary to do that. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Migrate the stateid reference into nfs4_find_stateid_by_type()Trond Myklebust1-6/+6
Allow nfs4_find_stateid_by_type to take the stateid reference, while still holding the &cl->cl_lock. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Migrate the stateid reference into nfs4_lookup_stateid()Trond Myklebust1-6/+11
Allow nfs4_lookup_stateid to take the stateid reference, instead of having all the callers do so. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Migrate the stateid reference into nfs4_preprocess_seqid_opTrond Myklebust1-15/+11
Allow nfs4_preprocess_seqid_op to take the stateid reference, instead of having all the callers do so. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add reference counting to nfs4_preprocess_confirmed_seqid_opTrond Myklebust1-4/+9
Ensure that all the callers put the open stateid after use. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: nfsd4_open_confirm() must reference the open stateidTrond Myklebust1-1/+5
Ensure that nfsd4_open_confirm() keeps a reference to the open stateid until it is done working with it. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Prepare nfsd4_close() for open stateid referencingTrond Myklebust1-0/+5
Prepare nfsd4_close for a future where nfs4_preprocess_seqid_op() hands it a fully referenced open stateid. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: nfsd4_process_open2() must reference the open stateidTrond Myklebust1-0/+4
Ensure that nfsd4_process_open2() keeps a reference to the open stateid until it is done working with it. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: nfsd4_process_open2() must reference the delegation stateidTrond Myklebust1-5/+13
Ensure that nfsd4_process_open2() keeps a reference to the delegation stateid until it is done working with it. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Ensure that nfs4_open_delegation() references the delegation stateidTrond Myklebust1-0/+2
Ensure that nfs4_open_delegation() keeps a reference to the delegation stateid until it is done working with it. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: nfsd4_locku() must reference the lock stateidTrond Myklebust1-1/+5
Ensure that nfsd4_locku() keeps a reference to the lock stateid until it is done working with it. Necessary step toward client_mutex removal. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add reference counting to lock stateidsTrond Myklebust1-3/+12
Ensure that nfsd4_lock() references the lock stateid while it is manipulating it. Not currently necessary, but will be once the client_mutex is removed. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: ensure atomicity in nfsd4_free_stateid and nfsd4_validate_stateidJeff Layton1-35/+36
Hold the cl_lock over the bulk of these functions. In addition to ensuring that they aren't freed prematurely, this will also help prevent a potential race that could be introduced later. Once we remove the client_mutex, it'll be possible for FREE_STATEID and CLOSE to race and for both to try to put the "persistent" reference to the stateid. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: clean up races in lock stateid searching and creationJeff Layton1-22/+49
Preparation for removal of the client_mutex. Currently, no lock aside from the client_mutex is held when calling find_lock_state. Ensure that the cl_lock is held by adding a lockdep assertion. Once we remove the client_mutex, it'll be possible for another thread to race in and insert a lock state for the same file after we search but before we insert a new one. Ensure that doesn't happen by redoing the search after allocating a new stid that we plan to insert. If one is found just put the one that was allocated. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add locking to protect the state owner listsJeff Layton1-2/+19
Change to using the clp->cl_lock for this. For now, there's a lot of cl_lock thrashing, but in later patches we'll eliminate that and close the potential races that can occur when releasing the cl_lock while walking the lists. For now, the client_mutex prevents those races. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: do filp_close in sc_free callback for lock stateidsJeff Layton1-8/+18
Releasing locks when we unhash the stateid instead of doing so only when the stateid is actually released will be problematic in later patches when we need to protect the unhashing with spinlocks. Move it into the sc_free operation instead. Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd4: use cl_lock to synchronize all stateid idr callsJeff Layton1-11/+30
Currently, this is serialized by the client_mutex, which is slated for removal. Add finer-grained locking here. Also, do some cleanup around find_stateid to prepare for taking references. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Benny Halevy <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add a struct nfs4_file field to struct nfs4_stidTrond Myklebust3-38/+36
All stateids are associated with a nfs4_file. Let's consolidate. Replace delegation->dl_file with the dl_stid.sc_file, and nfs4_ol_stateid->st_file with st_stid.sc_file. Signed-off-by: Trond Myklebust <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-31nfsd: Add reference counting to the lock and open stateidsTrond Myklebust3-50/+58
When we remove the client_mutex, we'll need to be able to ensure that these objects aren't destroyed while we're not holding locks. Add a ->free() callback to the struct nfs4_stid, so that we can release a reference to the stid without caring about the contents. Signed-off-by: Trond Myklebust <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: print status when nfsd4_open fails to open file it just createdJeff Layton2-1/+4
It's possible for nfsd to fail opening a file that it has just created. When that happens, we throw a WARN but it doesn't include any info about the error code. Print the status code to give us a bit more info. Our QA group hit some of these warnings under some very heavy stress testing. My suspicion is that they hit the file-max limit, but it's hard to know for sure. Go ahead and add a -ENFILE mapping to nfserr_serverfault to make the error more distinct (and correct). Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: remove dl_fh field from struct nfs4_delegationJeff Layton3-4/+2
Now that the nfs4_file has a filehandle in it, we no longer need to keep a per-delegation copy of it. Switch to using the one in the nfs4_file instead. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: give block_delegation and delegation_blocked its own spinlockJeff Layton1-10/+11
The state lock can be fairly heavily contended, and there's no reason that nfs4_file lookups and delegation_blocked should be mutually exclusive. Let's give the new block_delegation code its own spinlock. It does mean that we'll need to take a different lock in the delegation break code, but that's not generally as critical to performance. Cc: Neil Brown <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: clean up nfs4_set_delegationJeff Layton1-12/+22
Move the alloc_init_deleg call into nfs4_set_delegation and change the function to return a pointer to the delegation or an IS_ERR return. This allows us to skip allocating a delegation if the file has already experienced a lease conflict. Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: clean up arguments to nfs4_open_delegationJeff Layton1-6/+7
No need to pass in a net pointer since we can derive that. Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: drop unused stp arg to alloc_init_delegJeff Layton1-2/+2
Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: Convert delegation counter to an atomic_long_t typeTrond Myklebust1-7/+11
We want to convert to an atomic type so that we don't need to lock across the call to alloc_init_deleg(). Then convert to a long type so that we match the size of 'max_delegations'. None of this is a problem today, but it will be once we remove client_mutex protection. Signed-off-by: Trond Myklebust <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: ensure that clp->cl_revoked list is protected by clp->cl_lockJeff Layton1-15/+20
Currently, both destroy_revoked_delegation and revoke_delegation manipulate the cl_revoked list without any locking aside from the client_mutex. Ensure that the clp->cl_lock is held when manipulating it, except for the list walking in destroy_client. At that point, the client should no longer be in use, and so it should be safe to walk the list without any locking. That also means that we don't need to do the list_splice_init there either. Also, the fact that revoke_delegation deletes dl_recall_lru list_head without any locking makes it difficult to know whether it's doing so safely in all cases. Move the list_del_init calls into the callers, and add a WARN_ON in the event that t's passed a delegation that has a non-empty list_head. Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: fully unhash delegations when revoking themJeff Layton1-23/+21
Ensure that the delegations cannot be found by the laundromat etc once we add them to the various 'revoke' lists. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
2014-07-29nfsd: simplify stateid allocation and file handlingTrond Myklebust1-12/+10
Don't allow stateids to clear the open file pointer until they are being destroyed. In a later patches we'll want to rely on the fact that we have a valid file pointer when dealing with the stateid and this will save us from having to do a lot of NULL pointer checks before doing so. Also, move to allocating stateids with kzalloc and get rid of the explicit zeroing of fields. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>