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);
|
||||
}
|
||||
|
||||
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(
|
||||
IN struct nfs41_name_cache *cache,
|
||||
IN struct name_cache_entry *parent,
|
||||
|
|
@ -552,8 +562,9 @@ static struct name_cache_entry* name_cache_search(
|
|||
while (node) {
|
||||
entry = rb_entry(node, struct name_cache_entry, rbnode);
|
||||
|
||||
result = strncmp(component->name, entry->component,
|
||||
max(component->len, entry->component_len));
|
||||
result = component_cmp(component->name, component->len,
|
||||
entry->component, entry->component_len);
|
||||
|
||||
if (result < 0)
|
||||
node = node->rb_left;
|
||||
else if (result > 0)
|
||||
|
|
@ -658,7 +669,8 @@ static int name_cache_insert(
|
|||
while (*node) {
|
||||
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;
|
||||
if (result < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue