This answer https://stackoverflow.com/a/2099151/1084774 to Why do inode numbers start from 1 and not 0? states that inode number 0 is usable as a sentinel.
How portable is this usage, practically speaking?
CodePudding user response:
POSIX:
POSIX doesn't make any guarantees about inode numbers, so they can be zero and still be POSIX-compliant.
However, inode numbers can be very big, and specifically 4294967296 = 0x100000000 - namely 0 when truncated to 32 bits.
For this case, POSIX provides EOVERFLOW
:
[...] the file serial number cannot be represented correctly in the structure pointed to by buf.
Linux:
Linux has this function:
/*
* 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.
*
* As an additional complication, if userspace was compiled with
* _FILE_OFFSET_BITS=32 on a 64-bit kernel we'll only end up reading out the
* lower 32 bits, so we need to check that those aren't zero explicitly. With
* _FILE_OFFSET_BITS=64, this may cause some harmless false-negatives, but
* better safe than sorry.
*/
static inline bool is_zero_ino(ino_t ino)
{
return (u32)ino == 0;
}
However, it is currently used only by tmpfs. The Linux kernel filesystem doesn't dictate to filesystems whether or not inode 0 is allowed, but in practice, they all avoid inode number 0, and you will find that some of them actually do use inode 0 as a sentinel.
FreeBSD:
FreeBSD uses -1 (VNOVAL) as a sentinel, and does not dictate to filesystems whether or not they can use inode 0.
However, from surveying the filesystems supported by FreeBSD, they don't use inode 0.
MacOS:
As another answer on the linked thread says:
OSX specifies that inode 0 signifies a deleted file that has not yet been deleted;
NTFS:
Inode 0 is reserved for the MFT. MFT is not visible to users.
However, if your code is going to be used by the NTFS tools (mkfs, ntfsinfo, etc.) e.g. with NTFS-3G, then you can't assume that inode 0 doesn't exist.
Other major OSes and filesystems:
For a filesystem designer, allowing inode 0 to be a regular inode is just a headache. So it stands to reason that they will practically avoid it.
It's useful to treat it in a special way, but not necessarily as a sentinel. In filesystems where inode numbers are computed from on-disk offsets, it might be useful to have inode 0, but have it be internal.
Minor OSes and filesystems:
Writing filesystems is actually not very difficult these days, and a lot of people write toy filesystems, or real filesystems for environments like microcontrollers or other embedded environments.
There the variation could be much greater, and you shouldn't make any non-POSIX assumptions.
An example even exists in the linked thread.
The future:
While not likely, it is possible that the a future POSIX standard could codify inode 0 for some purpose, but not necessarily as a sentinel.
Conclusion:
Assuming inode 0 is not practically portable in the general sense, but it is practically portable across Linux and FreeBSD.