from Hacker News

In POSIX, you can theoretically use inode zero

by mfrw on 5/31/25, 8:57 AM with 38 comments

  • by the_mitsuhiko on 6/2/25, 8:51 AM

    The OpenBSD UFS documentation says this:

    > The root inode is the root of the file system. Inode 0 can't be used for normal purposes and historically bad blocks were linked to inode 1 (inode 1 is no longer used for this purpose; however, numerous dump tapes make this assumption, so we are stuck with it). Thus the root inode is 2.

    This is also echoed on the wikipedia page for it.

    The linux Kernel also has this comment for why it does not dish out that inode for shmem for instance:

    > Userspace may rely on the the inode number being non-zero. For example, glibc simply ignores files with zero i_ino in unlink() and other places.

    On macOS it's pretty clear that inode 0 is reserved:

    > Users of getdirentries() should skip entries with d_fileno = 0, as such entries represent files which have been deleted but not yet removed from the directory entry

  • by jcalvinowens on 6/2/25, 2:57 PM

    It used to happen on Linux with tmpfs, but kernel doesn't allow it anymore: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds...

    It turns out that glibc readdir() assumes inode zero doesn't happen and the files are "invisible" to anything using libc. But you can call getdents() directly and see them.

    I actually ran into this on a production machine once a few years ago, a service couldn't restart because a directory appeared to be "stuck" because it had one of these invisible zero inode files in it. It was very amusing, I figured it out by spotting the invisible filename in the strace output from getdents().

  • by nulld3v on 6/2/25, 8:29 AM

    Also, there seems to be an effort brewing in the kernel to push userspace away from depending on inode #s due to difficulty in guaranting uniqueness and stability across reboots. https://youtu.be/TNWK1zbTMOU
  • by Animats on 6/2/25, 7:04 AM

    It's been a long time since what user space sees as an "inode" has anything to do with the representation within the file system.
  • by duckerude on 6/2/25, 1:02 PM

    See also: https://internals.rust-lang.org/t/can-the-standard-library-s...

    A file descriptor can't be -1 but it's not 100% clear whether POSIX bans other negative numbers. So Rust's stdlib only bans -1 (for a space optimization) while still allowing for e.g. -2.

  • by etbebl on 6/3/25, 4:03 AM

    Isn't writing an article like this just daring someone to make the system in question more cursed, more likely to produce errors, harder to reason about, etc.? In the same spirit as, "well technically this common assumption about C behavior is undefined, so let's add some nasal demons to save 2 us (and make me look clever)"?

    Am I missing something or is this just evil? I guess I'm taking it too seriously.