name cache: bug fix for name_cache_search()
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>
This commit is contained in:
parent
c72007f076
commit
d345a7b12e
1 changed files with 15 additions and 3 deletions
|
|
@ -531,6 +531,16 @@ static void name_cache_entry_invalidate(
|
||||||
name_cache_unlink(cache, entry);
|
name_cache_unlink(cache, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int component_cmp(
|
||||||
|
IN const char *lhs,
|
||||||
|
IN unsigned short lhs_len,
|
||||||
|
IN const char *rhs,
|
||||||
|
IN unsigned short rhs_len)
|
||||||
|
{
|
||||||
|
const int diff = rhs_len - lhs_len;
|
||||||
|
return diff ? diff : strncmp(lhs, rhs, lhs_len);
|
||||||
|
}
|
||||||
|
|
||||||
static struct name_cache_entry* name_cache_search(
|
static struct name_cache_entry* name_cache_search(
|
||||||
IN struct nfs41_name_cache *cache,
|
IN struct nfs41_name_cache *cache,
|
||||||
IN struct name_cache_entry *parent,
|
IN struct name_cache_entry *parent,
|
||||||
|
|
@ -552,8 +562,9 @@ static struct name_cache_entry* name_cache_search(
|
||||||
while (node) {
|
while (node) {
|
||||||
entry = rb_entry(node, struct name_cache_entry, rbnode);
|
entry = rb_entry(node, struct name_cache_entry, rbnode);
|
||||||
|
|
||||||
result = strncmp(component->name, entry->component,
|
result = component_cmp(component->name, component->len,
|
||||||
max(component->len, entry->component_len));
|
entry->component, entry->component_len);
|
||||||
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
node = node->rb_left;
|
node = node->rb_left;
|
||||||
else if (result > 0)
|
else if (result > 0)
|
||||||
|
|
@ -658,7 +669,8 @@ static int name_cache_insert(
|
||||||
while (*node) {
|
while (*node) {
|
||||||
current = rb_entry(*node, struct name_cache_entry, rbnode);
|
current = rb_entry(*node, struct name_cache_entry, rbnode);
|
||||||
|
|
||||||
result = strcmp(entry->component, current->component);
|
result = component_cmp(entry->component, entry->component_len,
|
||||||
|
current->component, current->component_len);
|
||||||
|
|
||||||
prev = *node;
|
prev = *node;
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue