3 ms·
O_EXCL and RENAME_NOREPLACE are examples of why you want case insensitivity to be in the kernel. They're atomic operations: if you use O_EXCL, you could get a
by comex 8y ago
O_EXCL and RENAME_NOREPLACE are examples of why you want case insensitivity to be in the kernel. They're atomic operations: if you use O_EXCL, you could get a successful file creation, or you could get EEXIST, but not something in between. But you can't implement a case insensitive version of O_EXCL in userland. As I said, the best you can do is scan first to see whether a conflicting file already exists, but that doesn't help if a conflicting file is created in between the scan and when you create your file.
The kernel is in a better position; since all readers and writers must go through the kernel's filesystem routines, those routines can use mutexes or other concurrency mechanisms (that they need anyway to protect their data structures) to implement higher-level atomic semantics. That's how the kernel implements regular O_EXCL, and it's how it can implement case-insensitive O_EXCL as well, without having to deal with race conditions. In fact it already does that for vfat and other case-insensitive filesystems.
(A FUSE filesystem similarly gatekeeps all accesses and thus can do the job in userspace, but FUSE is slow.)
- nybble41 8y ago> But you can't implement a case insensitive version of O_EXCL in userland. So leave O_EXCL in the kernel in its current case-sensitive form. In userspace, implement normalization and case-folding as you see fit and pass the normalized, case-folded filename to open(). Ignore any files other programs may create with non-normalized names. Keep an xattr or lookup table with the unfolded "presentation" version of the name for directory listings.