namecache: fix for negative entries on rename

this addresses two error cases:

1) when the src entry is negative or does not exist: the dst entry could be negative or point to something else, so it needs to be removed
2) when the dst_parent entry is negative or does not exist: src needs to be made a negative entry

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2011-11-04 16:10:36 -04:00 committed by unknown
parent 68252b6522
commit 7f82baf13f

View file

@ -1115,18 +1115,31 @@ int nfs41_name_cache_rename(
goto out_unlock; goto out_unlock;
} }
/* look up dst_parent */
status = name_cache_lookup(cache, 0, dst_path,
dst_name->name, NULL, NULL, &dst_parent, NULL);
/* we can't create the dst entry without a parent */
if (status || dst_parent->attributes == NULL) {
/* if src exists, make it negative */
status = name_cache_lookup(cache, 0, src_path,
src_name->name + src_name->len, NULL, NULL, &src, NULL);
if (status == NO_ERROR) {
name_cache_entry_update(cache, src, NULL, NULL, OPEN_DELEGATE_NONE);
name_cache_unlink_children_recursive(cache, src);
}
status = ERROR_PATH_NOT_FOUND;
goto out_unlock;
}
/* look up src_parent and src */ /* look up src_parent and src */
status = name_cache_lookup(cache, 0, src_path, status = name_cache_lookup(cache, 0, src_path,
src_name->name + src_name->len, NULL, &src_parent, &src, NULL); src_name->name + src_name->len, NULL, &src_parent, &src, NULL);
/* we can't create the dst entry without valid attributes */ /* we can't create the dst entry without valid attributes */
if (status || src->attributes == NULL) if (status || src->attributes == NULL) {
goto out_unlock; /* remove dst if it exists */
struct name_cache_entry *dst;
/* look up dst_parent */ dst = name_cache_search(cache, dst_parent, dst_name);
status = name_cache_lookup(cache, 0, dst_path, if (dst) name_cache_unlink(cache, dst);
dst_name->name, NULL, NULL, &dst_parent, NULL);
if (status) {
status = ERROR_PATH_NOT_FOUND;
goto out_unlock; goto out_unlock;
} }