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>
added 2011 year to the copyright line
added authors info to the license
added UofM license to libtirpc files that we modified
(but i probably missed some)
when a delegation is granted by OPEN, its delegation type is passed to nfs41_name_cache_insert(). as long as the delegation is held, its name_cache_entry is kept out of the cache.exp_entries list to prevent it from expiring. an extra reference is held on the attr_cache_entry as well, so it sticks around even if the name_cache_entry is removed (a parent expires, for example). new function nfs41_name_cache_delegreturn() adds the name_cache_entry back to the list, and releases the extra attr_cache_entry reference
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
nfs41_name_cache_lookup() was returning FILE_NOT_FOUND on negative entries, but still copying the target filehandle
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
avoid the recursive case where state recovery operations (OPEN for reclaim and RECLAIM_COMPLETE) return BADSESSION, which kicks off another round of recovery
added a 'bool_t try_recovery' argument to compound_encode_send_decode() in place of its unused 'bufsize_in' and 'bufsize_out'. when try_recovery=FALSE, return BADSESSION/STALE_CLIENTID errors instead of attempting recovery. nfs41_open_reclaim(), nfs41_reclaim_complete(), and nfs41_destroy_session() now pass try_recovery=FALSE
during state recovery, we can now check the return values of nfs41_open_reclaim() and nfs41_reclaim_complete() for BADSESSION, and use a goto to restart session recovery
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
fixed a few cases of warning 4242: possible loss of data
wincrypt.h appears to come with windows.h in later versions of the ddk, but nfs41_client.c fails to compile in WDK 6001 without #include <wincrypt.h>
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
symptom: in certain cases, name_cache_find_or_create() was returning ERROR_FILE_EXISTS, which should never happen!
cause: the string comparisons in name_cache_search() and name_cache_insert() were returning different results when the argument to name_cache_search() is a) not null-terminated, and b) shorter than the other string. this caused name_cache_search() to search the wrong branch of the rbtree and fail to find the component, while name_cache_insert() would correctly find it and return ERROR_FILE_EXISTS
fix: compare the string lengths before calling strncmp() to avoid comparing past the end of the component. moved the comparisons to a separate component_cmp() function called by both name_cache_search() and name_cache_insert() to make sure they get the same result!
Signed-off-by: Casey Bodley <cbodley@umich.edu>
/* negative lookup caching
*
* by caching lookups that result in NOENT, we can avoid sending subsequent
* lookups over the wire. a name cache entry is negative when its attributes
* pointer is NULL. negative entries are created by three functions:
* nfs41_name_cache_remove(), _insert() when called with NULL for the fh and
* attributes, and _rename() for the source entry
*/
Signed-off-by: Casey Bodley <cbodley@umich.edu>
previously, when the name cache encountered a missing/negative/expired entry, it returned the previous two entries as 'target' and 'parent', and nfs41_lookup() started new lookups from the filehandle in 'target'. this differs from nfs41_lookup(), which on NOENT will return NULL for the 'target' and the previous entry as 'parent'. modified name_cache_lookup() to do the same, and updated nfs41_lookup() to start new lookups from the filehandle in 'parent'
now when nfs41_lookup() gets the is_negative flag from nfs41_name_cache_lookup(), it can just return the error without needing to copy the 'target' to 'parent'
Signed-off-by: Casey Bodley <cbodley@umich.edu>
as before, we move the src entry from src_parent to dst_parent. but instead of unlinking the destination entry if it exists, we recycle it as a negative entry where src used to be. if the destination entry doesn't exist, we create a new one for this negative entry
if the dst_parent entry is invalidated by the change_info, we just leave the original src entry in place and make it negative
Signed-off-by: Casey Bodley <cbodley@umich.edu>
negative lookup entries don't have attributes, so we won't invalidate them based on 'change'. name_cache_entry_changed() returns false if entry->attributes == NULL
Signed-off-by: Casey Bodley <cbodley@umich.edu>
instead of calling name_cache_entry_unlink(), nfs41_name_cache_remove() calls name_cache_entry_update() with NULL for fh and info to make it a negative entry, then name_cache_unlink_children_recursive() to remove any children
Signed-off-by: Casey Bodley <cbodley@umich.edu>
marked nfs41_name_cache_insert() parameters fh and info as OPTIONAL; passing NULL designates a negative lookup entry
name_cache_entry_create() no longer calls attr_cache_find_or_create(), and doesn't need the 'fileid' argument
name_cache_entry_update() also makes fh and info OPTIONAL, and handles the cases where we switch from a negative <-> positive entry, calling attr_cache_find_or_create() or attr_cache_entry_deref() as appropriate
removed unused function name_cache_find_or_create(); everything uses name_cache_entry_find_or_create() instead, so renamed that to name_cache_find_or_create()
Signed-off-by: Casey Bodley <cbodley@umich.edu>
added function entry_invis() in addition to entry_has_expired(). entry_invis() returns true if entry_has_expired() or for negative entries. the is_negative flag is set for negative entries (defined as having entry->attributes == NULL), and returned by nfs41_name_cache_lookup(). when nfs41_lookup() sees this flag set, it returns the status without attempting to do any more lookups
Signed-off-by: Casey Bodley <cbodley@umich.edu>