A case-insensitive filesystem just means that whenever the filesystem has to ask "does A refer to the same file/directory as B?" it compares the names of files/directories ignoring differences in upper/lowercase (exactly what upper/lowercase differences count depends on the filesystem—it's non-obvious once you get beyond ASCII). A case-sensitive filesystem does not ignore those differences.
A case-preserving filesystem stores file names as given. A non-case-preserving filesystem does not; it'll typically convert all letters to uppercase before storing them (theoretically, it could use lowercase, or RaNsOm NoTe case, or whatever, but AFAIK all real-world ones used uppercase).
You can put those two attributes together in any combination. I'm not sure if you can find non-case-preserving case-sensitive filesystems, but you could certainly create one. All the other combinations exist or existed in real systems, though.
So a case-preserving, case-insensitive filesystem (the most common type of case-insensitive filesystem nowadays) will store and return file names in whatever capitalization you created them or last renamed them, but when comparing two file names (to check if one exists, to open one, to delete one, etc.) it'll ignore case differences.
When you use a case-insensitive filesystem on a Unix box, various utilities will do weird things because Unix traditionally uses case-sensitive filesystems—so they're not expecting Document1
and document1
to be the same file.
In the pwd
case, what you're seeing is that it by default just outputs the path you actually used to get to the directory. So if you got there via cd DirName
, it'll use DirName
in the output. If you got there via DiRnAmE
, you'll see DiRnAmE
in the output. Bash does this by keeping track of how you got to your current directory in the $PWD
environment variable. Mainly this is for symlinks (if you cd
into a symlink, you'll see the symlink in your pwd
, even though it's actually not part of the path to your current directory). But it also gives the somewhat weird behavior you observe on case-insensitive filesystems. I suspect that pwd -P
will give you the directory name using the case stored on disk, but haven't tested.
Best Answer
Wine, Samba, and Android have to provide case-insensitive filesystem semantics. If the underlying filesystem is case-sensitive, every time a case-sensitive lookup fails, Wine et al. has to scan each directory to prove there are no case-insensitive matches (e.g. if looking up
/foo/bar/readme.txt
fails, you have to perform a full directory listing and case-folded comparison of all files infoo/bar/*
and all directories infoo/*
, and/*
).There are a few problems with this:
readme.txt
andREADME.txt
exist but an application asks forREADME.TXT
, which file is returned is undefined.Android went so far as to emulate case-insensitivity using FUSE/wrapfs and then the in-kernel SDCardFS. However, SDCardFS just made everything faster by moving the process into kenel space†. It still had to walk the filesystem (and was thus IO bound), introduced race conditions, and was fundamentally unsound. Hence why Google funded† development of native per-directory case-insensitivity in F2FS and have since deprecated SDCardFS.
There have been multiple attempts in the past to enable case-insensitive lookups via VFS. The most recent attempt in 2018 allowed mounting a case-insensitive view of the filesystem. Ted Tso specifically cited the issues with wrapfs for adding this functionality, as it would at least be faster and (I believe) free of race conditions. However, it was still unsound (requesting
README.TXT
could returnreadme.txt
orREADME.txt
). This was rejected in favor of just adding per-directory support for case-insensitivity and is unlikely to ever make it into VFS††.Furthermore, users expect case-insensitivity thus any consumer oriented operating system has to provide it. Unix couldn't supported it natively because Unicode didn't exist and strings were just bags-of-bytes. There are plenty of valid criticisms of how case-folding was handled in the past, but Unicode provides an immutable case-fold function that works for all but a single locale (Turkic, and even then it's just two codepoints). And the filesystem b-tree is the only reasonable place to implement this behavior.
†AFAICT
††I emailed Krisman, the author of both the VFS-based case-insensitive lookups and per-directory case-insensitive support on EXT4 and F2FS.