was doing a memcpy from entry->u.QueryFile.buf to RxContext->Info.Buffer, even though we set entry->u.QueryFile.buf = RxContext->Info.Buffer
Signed-off-by: Casey Bodley <cbodley@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>
the link part of basic test7 was failing because LINK's target was still cached as a negative entry, leading to the error "can't stat newfile.0 after link". the solution is to replace the negative entry with the real fh and attributes of the target file
so instead of doing RESTOREFH+GETATTR on the source file and calling nfs41_attr_cache_update(), nfs41_link() uses LOOKUP+GETATTR+GETFH to get attributes for the target file and passes them to nfs41_name_cache_insert() along with dst_dir's changeinfo. because the source and target file will have the same fileid attribute, nfs41_name_cache_insert() will update the attributes of both at the same time. added the target file as an optional return parameter
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>