How are files/dirs hidden from ls -a while still being accessible otherwise in a POSIX compliant system

dot-filesfilesystemsposixzfs

For example, in ZFS under FreeBSD and ZoL, there is a magic .zfs dir inside of each zpool mountpoint and you can use zfs set snapdir=visible to make that .zfs dir visible.

What makes me curious is: if that setting is set to "hidden", how is the .zfs dir actually hidden from the output of an ls -a or shell path-auto-completion, while still being accessible otherwise (you can still cd to it or call stat on it)?

I can't really wrap my mind around this fact, because I somehow think if something is there and accessible it's supposed to be listed in ls -a — even if it's just magic/virtual in nature.

Can anybody explain how this works? Is there a POSIX conforming way to have a directory that is hidden from ls -a while still being accessible? How do you do it?

Best Answer

Well, how to do it is easy enough: ls gets its list from a syscall (or, on Linux, libc function) called readdir. Changing into a directory is done with a separate syscall, chdir. stat is also a different syscall, as are most of the other file operations.

In short, "what's in this directory?" and "access this directory" are completely separate requests of the kernel—so they can be programmed to work differently.

So, to make a directory that doesn't appear in ls -a, you just have the kernel omit it from the results of readdir. But it still works with chdir (etc.), because that's a different syscall.

This isn't so different from having a directory where you have +x permission, but not -r: you can access files and directories inside it, cd into it, etc., but ls will fail. I believe other things have used this arrangement too—for example (and this is from fuzzy memory without looking it up) AFS had a sort-of global /afs namespace where you could connect to any AFS server essentially by cd'ing into its name; an ls on /afs wouldn't show all the world's servers, though. I've seen FUSE filesystems do similar (e.g., cd to connect to an anonymous FTP server).

(I'm not sure whether the zfs arrangement strictly complies with POSIX).