name cache: lookup returns flag is_negative
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>
This commit is contained in:
parent
55ff9d855d
commit
112313bc45
3 changed files with 39 additions and 21 deletions
|
|
@ -427,6 +427,7 @@ int nfs41_lookup(
|
||||||
nfs41_path_fh parent, target, *server_start;
|
nfs41_path_fh parent, target, *server_start;
|
||||||
const char *path_pos, *path_end;
|
const char *path_pos, *path_end;
|
||||||
struct lookup_referral referral;
|
struct lookup_referral referral;
|
||||||
|
bool_t negative = 0;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (session_out) *session_out = session;
|
if (session_out) *session_out = session;
|
||||||
|
|
@ -448,10 +449,9 @@ int nfs41_lookup(
|
||||||
if (target_out == NULL) target_out = ⌖
|
if (target_out == NULL) target_out = ⌖
|
||||||
parent_out->fh.len = target_out->fh.len = 0;
|
parent_out->fh.len = target_out->fh.len = 0;
|
||||||
|
|
||||||
status = nfs41_name_cache_lookup(cache,
|
status = nfs41_name_cache_lookup(cache, path_pos, path_end, &path_pos,
|
||||||
path_pos, path_end, &path_pos,
|
&parent_out->fh, &target_out->fh, info_out, &negative);
|
||||||
&parent_out->fh, &target_out->fh, info_out);
|
if (status == NO_ERROR || negative)
|
||||||
if (status == NO_ERROR)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (target_out->fh.len) {
|
if (target_out->fh.len) {
|
||||||
|
|
|
||||||
|
|
@ -545,7 +545,7 @@ out_success:
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int entry_has_expired(
|
static int entry_has_expired(
|
||||||
IN struct name_cache_entry *entry)
|
IN struct name_cache_entry *entry)
|
||||||
{
|
{
|
||||||
/* invalidated by another entry or timer expired */
|
/* invalidated by another entry or timer expired */
|
||||||
|
|
@ -557,14 +557,30 @@ static __inline int entry_has_expired(
|
||||||
return expired;
|
return expired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int entry_invis(
|
||||||
|
IN struct name_cache_entry *entry,
|
||||||
|
OUT OPTIONAL bool_t *is_negative)
|
||||||
|
{
|
||||||
|
if (entry_has_expired(entry))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* a negative lookup entry has an empty fh and no attributes */
|
||||||
|
if (entry->attributes == NULL) {
|
||||||
|
if (is_negative) *is_negative = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int name_cache_lookup(
|
static int name_cache_lookup(
|
||||||
IN struct nfs41_name_cache *cache,
|
IN struct nfs41_name_cache *cache,
|
||||||
IN bool_t skip_expired,
|
IN bool_t skip_invis,
|
||||||
IN const char *path,
|
IN const char *path,
|
||||||
IN const char *path_end,
|
IN const char *path_end,
|
||||||
OUT OPTIONAL const char **remaining_path_out,
|
OUT OPTIONAL const char **remaining_path_out,
|
||||||
OUT OPTIONAL struct name_cache_entry **parent_out,
|
OUT OPTIONAL struct name_cache_entry **parent_out,
|
||||||
OUT OPTIONAL struct name_cache_entry **target_out)
|
OUT OPTIONAL struct name_cache_entry **target_out,
|
||||||
|
OUT OPTIONAL bool_t *is_negative)
|
||||||
{
|
{
|
||||||
struct name_cache_entry *parent, *target, *tmp;
|
struct name_cache_entry *parent, *target, *tmp;
|
||||||
nfs41_component component;
|
nfs41_component component;
|
||||||
|
|
@ -577,7 +593,7 @@ static int name_cache_lookup(
|
||||||
target = cache->root;
|
target = cache->root;
|
||||||
component.name = path_pos = path;
|
component.name = path_pos = path;
|
||||||
|
|
||||||
if (target == NULL || (skip_expired && entry_has_expired(target))) {
|
if (target == NULL || (skip_invis && entry_invis(target, is_negative))) {
|
||||||
target = NULL;
|
target = NULL;
|
||||||
status = ERROR_PATH_NOT_FOUND;
|
status = ERROR_PATH_NOT_FOUND;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -585,7 +601,7 @@ static int name_cache_lookup(
|
||||||
|
|
||||||
while (next_component(path_pos, path_end, &component)) {
|
while (next_component(path_pos, path_end, &component)) {
|
||||||
tmp = name_cache_search(cache, target, &component);
|
tmp = name_cache_search(cache, target, &component);
|
||||||
if (tmp == NULL || (skip_expired && entry_has_expired(tmp))) {
|
if (tmp == NULL || (skip_invis && entry_invis(tmp, is_negative))) {
|
||||||
if (is_last_component(component.name, path_end))
|
if (is_last_component(component.name, path_end))
|
||||||
status = ERROR_FILE_NOT_FOUND;
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
else
|
else
|
||||||
|
|
@ -695,7 +711,7 @@ static int name_cache_find_or_create(
|
||||||
dprintf(NCLVL1, "--> name_cache_find_or_create('%s')\n", path);
|
dprintf(NCLVL1, "--> name_cache_find_or_create('%s')\n", path);
|
||||||
|
|
||||||
status = name_cache_lookup(cache, 0, path, path_end,
|
status = name_cache_lookup(cache, 0, path, path_end,
|
||||||
&path_pos, &parent, target_out);
|
&path_pos, &parent, target_out, NULL);
|
||||||
if (status != ERROR_FILE_NOT_FOUND)
|
if (status != ERROR_FILE_NOT_FOUND)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
@ -816,7 +832,8 @@ int nfs41_name_cache_lookup(
|
||||||
OUT OPTIONAL const char **remaining_path_out,
|
OUT OPTIONAL const char **remaining_path_out,
|
||||||
OUT OPTIONAL nfs41_fh *parent_out,
|
OUT OPTIONAL nfs41_fh *parent_out,
|
||||||
OUT OPTIONAL nfs41_fh *target_out,
|
OUT OPTIONAL nfs41_fh *target_out,
|
||||||
OUT OPTIONAL nfs41_file_info *info_out)
|
OUT OPTIONAL nfs41_file_info *info_out,
|
||||||
|
OUT OPTIONAL bool_t *is_negative)
|
||||||
{
|
{
|
||||||
struct name_cache_entry *parent, *target;
|
struct name_cache_entry *parent, *target;
|
||||||
const char *path_pos = path;
|
const char *path_pos = path;
|
||||||
|
|
@ -830,7 +847,7 @@ int nfs41_name_cache_lookup(
|
||||||
}
|
}
|
||||||
|
|
||||||
status = name_cache_lookup(cache, 1, path, path_end,
|
status = name_cache_lookup(cache, 1, path, path_end,
|
||||||
&path_pos, &parent, &target);
|
&path_pos, &parent, &target, is_negative);
|
||||||
|
|
||||||
if (parent_out) copy_fh(parent_out, parent);
|
if (parent_out) copy_fh(parent_out, parent);
|
||||||
if (target_out) copy_fh(target_out, target);
|
if (target_out) copy_fh(target_out, target);
|
||||||
|
|
@ -946,7 +963,7 @@ int nfs41_name_cache_insert(
|
||||||
}
|
}
|
||||||
|
|
||||||
status = name_cache_lookup(cache, 0, path, name->name,
|
status = name_cache_lookup(cache, 0, path, name->name,
|
||||||
NULL, &grandparent, &parent);
|
NULL, &grandparent, &parent, NULL);
|
||||||
if (status)
|
if (status)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
|
@ -989,7 +1006,7 @@ int nfs41_name_cache_remove(
|
||||||
}
|
}
|
||||||
|
|
||||||
status = name_cache_lookup(cache, 0, path,
|
status = name_cache_lookup(cache, 0, path,
|
||||||
name->name + name->len, NULL, &parent, &target);
|
name->name + name->len, NULL, &parent, &target, NULL);
|
||||||
if (status == ERROR_PATH_NOT_FOUND)
|
if (status == ERROR_PATH_NOT_FOUND)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
|
@ -1036,13 +1053,13 @@ int nfs41_name_cache_rename(
|
||||||
|
|
||||||
/* get src_parent and target */
|
/* get src_parent and target */
|
||||||
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, &target);
|
src_name->name + src_name->len, NULL, &src_parent, &target, NULL);
|
||||||
if (status)
|
if (status)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
/* get dst_parent */
|
/* get dst_parent */
|
||||||
status = name_cache_lookup(cache, 0, dst_path,
|
status = name_cache_lookup(cache, 0, dst_path,
|
||||||
dst_name->name, NULL, NULL, &dst_parent);
|
dst_name->name, NULL, NULL, &dst_parent, NULL);
|
||||||
if (status) {
|
if (status) {
|
||||||
status = ERROR_PATH_NOT_FOUND;
|
status = ERROR_PATH_NOT_FOUND;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
@ -1089,8 +1106,8 @@ static bool_t get_path_fhs(
|
||||||
AcquireSRWLockShared(&cache->lock);
|
AcquireSRWLockShared(&cache->lock);
|
||||||
|
|
||||||
/* look up the parent of the first component */
|
/* look up the parent of the first component */
|
||||||
status = name_cache_lookup(cache, 1, path->path, *path_pos,
|
status = name_cache_lookup(cache, 1, path->path,
|
||||||
NULL, NULL, &target);
|
*path_pos, NULL, NULL, &target, NULL);
|
||||||
if (status)
|
if (status)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
|
@ -1103,7 +1120,7 @@ static bool_t get_path_fhs(
|
||||||
*path_pos = name->name + name->len;
|
*path_pos = name->name + name->len;
|
||||||
|
|
||||||
target = name_cache_search(cache, target, name);
|
target = name_cache_search(cache, target, name);
|
||||||
if (target == NULL || entry_has_expired(target)) {
|
if (target == NULL || entry_invis(target, NULL)) {
|
||||||
if (is_last_component(name->name, path_end))
|
if (is_last_component(name->name, path_end))
|
||||||
status = ERROR_FILE_NOT_FOUND;
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
else
|
else
|
||||||
|
|
@ -1183,7 +1200,7 @@ static int delete_stale_component(
|
||||||
AcquireSRWLockExclusive(&cache->lock);
|
AcquireSRWLockExclusive(&cache->lock);
|
||||||
|
|
||||||
status = name_cache_lookup(cache, 0, path->path,
|
status = name_cache_lookup(cache, 0, path->path,
|
||||||
component->name + component->len, NULL, NULL, &target);
|
component->name + component->len, NULL, NULL, &target, NULL);
|
||||||
if (status == NO_ERROR)
|
if (status == NO_ERROR)
|
||||||
name_cache_unlink(cache, target);
|
name_cache_unlink(cache, target);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ int nfs41_name_cache_lookup(
|
||||||
OUT OPTIONAL const char **remaining_path_out,
|
OUT OPTIONAL const char **remaining_path_out,
|
||||||
OUT OPTIONAL nfs41_fh *parent_out,
|
OUT OPTIONAL nfs41_fh *parent_out,
|
||||||
OUT OPTIONAL nfs41_fh *target_out,
|
OUT OPTIONAL nfs41_fh *target_out,
|
||||||
OUT OPTIONAL nfs41_file_info *info_out);
|
OUT OPTIONAL nfs41_file_info *info_out,
|
||||||
|
OUT OPTIONAL bool_t *is_negative);
|
||||||
|
|
||||||
int nfs41_name_cache_insert(
|
int nfs41_name_cache_insert(
|
||||||
IN struct nfs41_name_cache *cache,
|
IN struct nfs41_name_cache *cache,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue