Home > Net >  Portability inode number 0 as a sentinel
Portability inode number 0 as a sentinel

Time:11-28

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.

  • Related