the out_err_deleg: case of nfs41_name_cache_insert() was forgetting to increment cache->delegations, leading to a decrement past 0. once that happens, the cache stops accepting delegations because it's comparing cache->max_delegations against UINT_MAX
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
iozone tests were failing intermittently against emc-2 due to out-of-order LAYOUTCOMMITs that both specified new_last_offset
nfs41_open_state now maintains a cached value of the last_offset, and avoids sending it with LAYOUTCOMMIT unless the new last_offset is greater than the cached offset. this cached value is initialized on open/delegation, and updated on setattr for size
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
sorry, earlier Casey, but the patch 'threading by io unit instead of stripe' from 6/20/2010 was nuts! with PNFS_THREAD_BY_SERVER disabled, we definitely -don't- want to create a separate thread for each io unit (each READ/WRITE request to a ds). we just want the one per stripe, as the intended alternative to PNFS_THREAD_BY_SERVER
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
cancel_lock() can't rely on checking upcall.status, because a handle_lock() success could be overwritten by upcall_marshall() or failure to allocate the upcall reply buffer. added new flag lock_upcall_args.acquired for this purpose
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
now that cancel_lock() and handle_unlock() depend on finding lock state in the open, the comment /* ignore errors from open_lock_add(); they just mean we won't be able to recover the lock after reboot */ no longer applies. allocate the lock state at the top of handle_lock(), so we can bail immediately on failure
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
removed unused variable 'grandparent'
factored out the call to name_cache_entry_update() from root/non-root paths
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
renamed name_cache_entry_refresh() to name_cache_entry_updated(). this function resets the entry's expiration timer. new function name_cache_entry_accessed() deals with moving the entry to the end of exp_entries to prevent eviction
name_cache_entry_accessed() now does the same for its parents as well. cache consistency of the parents is maintained because their expiration timers are unchanged. by 'refreshing' the parents of each name cache entry inserted, the eviction policy will always prefer child nodes (which are far less costly to evict)
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
open_update_cache() wasn't retrying insert after the open_delegation_return() error case
nfs41_name_cache_delegreturn() needs a check for if (attributes->delegated) to avoid an extra deref when the call to nfs41_name_cache_insert() failed
added a TODO comment to nfs41_client_delegation_return_lru() for improvements to the naive algorithm
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when marshalling of the open downcall or allocating buffer for the downcall
fails, upcall.status gets set but we still need to cancel the open we
just did. instead check for non-allocated open state as evidence that
handle_open() failed and we don't need to cancel vs the other failure.
windows api frequently sends a query security with a buffer len of 0
to figure out how big of buffer is needed for a security descriptor.
we send a getattr for acl attribute on the 1st irp, then cache the
returned security descriptor in fobx. on the 2nd query, if the buffer
is cached and it's not "stale", we return that buffer.
to prevent delegations from claiming all available slots in the attribute cache, nfs41_name_cache_insert() now returns ERROR_TOO_MANY_OPEN_FILES when the number of delegated entries reaches 50% of the cache capacity. see comment 'delegations and cache feedback' in name_cache.c for details
when nfs41_open() sees this error from nfs41_name_cache_insert(), it calls new function nfs41_client_delegation_return_lru() to return the least-recently-used delegation and, if successful, loops back to nfs41_name_cache_insert(). nfs41_client_delegation_return_lru() returns NFS4ERR_BADHANDLE if all delegations are currently in use (associated with an existing open), in which case nfs41_open() returns the newly-granted delegation
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
on opens that grant a delegation, return the delegation immediately if attribute cache insertion fails
nfs41_name_cache_insert() now returns success in the 'out_err_deleg' case, where name cache insertion failed but attr cache insertion was successful
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
once the attribute cache fills up with delegated entries, attr_cache_find_or_create() will start returning ERROR_OUTOFMEMORY. this is a problem for nfs41_name_cache_insert(), because name_cache_find_or_create() will succeed and then name_cache_entry_update() will fail. this leaves behind a name cache entry with attributes=NULL, which is treated like a negative entry and causes later lookups to fail with ERROR_FILE_NOT_FOUND
added a call to name_cache_entry_invalidate() to clean up this entry if name_cache_entry_update() fails
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>