Re: Msdos patch for aliased names

Alain Knaff (alknaff@innet.lu)
Wed, 30 Jul 1997 00:35:15 +0200


>
>
>On Mon, 28 Jul 1997 alknaff@innet.lu wrote:
>>
>> In order to avoid these problems, the filenames are not transformed
>> into "canonic" filenames, which allow only one representation per
>> valid MSDOS directory entry. Unfortunately, the name_translate_char
>> mechanism was not enough for that, because canonizing an MSDOS
>> filename may change its length (if for instance the basename was
>> longer than 8 characters, but also when using names without extension,
>> which can be represented with or without a trailing dot).
>
>I don't want to apply this patch because it slows down a critical path.

In which way does it slow down the critical path? Is it the
kmalloc() in msdos_canonize that you're worried about, or is it
something else?

>Instead, could we maybe just simplify the canonicalization of msdos
>filenames? Simplify it enough that name_translate_char() would be
>sufficient? The rules would be:
>
> - no suffix -> no dot
> - basename > 8 characters -> can't happen

ok

> - forget about hidden files and the prepending '.'

this shouldn't be a problem anyways...

>None of the above rules are very fascistic - they'd simplify things a lot,
>and I think the old logic is too complex to be really worth maintaining.
>
> Linus
>

However, while trying to implement name_translate_char based
canonizing, two things occurred to me:
1. Actually, apart from the kmalloc, name_translate_char's impact
would be worse, because it has to be tested for and invoked for every
character, as opposed to once per name part.
2. We have currently the following code in lookup_dentry:

do {
len++; name++;
c = name_translate_char(base, c);
hash = partial_name_hash(c, hash);
c = *name;
} while (c && (c != '/'));

This doesn't actually modify the name, but only its hash value.
However, hash value equality is not enough to make to qstrs match, as
we use the following code in __dlookup:

while (tmp != head) {
struct dentry * dentry = list_entry(tmp, struct dentry, d_hash);

tmp = tmp->next;
if (dentry->d_name.hash != hash)
continue;
if (dentry->d_name.len != len)
continue;
if (dentry->d_parent != parent)
continue;
** if (memcmp(dentry->d_name.name, str, len))
** continue;
return dentry;
}
return NULL;

Note the memcmp near the end. However, "fixing" the code from
lookup_dentry by adding a *name = c; wouldn't work because name is a
const char *. And I suppose that it is declared const for a good
reason (I can imagine that scribbling over the name might do
interesting things if the name comes from a symlink: we would directly
scribble over the buffer...). Another idea would be to replace the
memcmp in __dlookup by a filesystem-specific comparison function.
Would that slow down the critical path? (Considering that this time no
kmalloc is involved, and that we are out of the critical path because
the comparison of the hash value should catch most non-matching
entries). And what about adding a filesystem specific method of
calculating the hash value instead of the above-listed lookup_dentry
code?

Regards,

Alain