Re: [RFC PATCH 2/4] mm: shmem: Support case-insensitive file name lookups
From: Al Viro <viro@zeniv.linux.org.uk>
Date: 2021-03-23 23:24:07
Also in:
linux-fsdevel, lkml
On Tue, Mar 23, 2021 at 04:59:39PM -0300, André Almeida wrote:
* dcache handling: For a +F directory, tmpfs only stores the first equivalent name dentry used in the dcache. This is done to prevent unintentional duplication of dentries in the dcache, while also allowing the VFS code to quickly find the right entry in the cache despite which equivalent string was used in a previous lookup, without having to resort to ->lookup(). d_hash() of casefolded directories is implemented as the hash of the casefolded string, such that we always have a well-known bucket for all the equivalencies of the same string. d_compare() uses the utf8_strncasecmp() infrastructure, which handles the comparison of equivalent, same case, names as well. For now, negative lookups are not inserted in the dcache, since they would need to be invalidated anyway, because we can't trust missing file dentries. This is bad for performance but requires some leveraging of the VFS layer to fix. We can live without that for now, and so does everyone else.
"For now"? Not a single practical suggestion has ever materialized. Pardon me, but by now I'm very sceptical about the odds of that ever changing. And no, I don't have any suggestions either.
The lookup() path at tmpfs creates negatives dentries, that are later instantiated if the file is created. In that way, all files in tmpfs have a dentry given that the filesystem exists exclusively in memory. As explained above, we don't have negative dentries for casefold files, so dentries are created at lookup() iff files aren't casefolded. Else, the dentry is created just before being instantiated at create path. At the remove path, dentries are invalidated for casefolded files.
Umm... What happens to those assertions if previously sane directory gets case-buggered? You've got an ioctl for doing just that... Incidentally, that ioctl is obviously racy - result of that simple_empty() might have nothing to do with reality before it is returned to caller. And while we are at it, simple_empty() doesn't check a damn thing about negative dentries in there...