How Does an Inode Store Metadata and Block Pointers?

An inode, short for index node, is a fundamental data structure in Unix and Unix-like file systems that stores all the attributes and disk location pointers for a file or directory, completely separate from its human-readable filename. By decoupling a file's identity and physical storage layout from its name, the file system can support features like hard links, atomic renames, and consistent permission enforcement.

Separation of Filenames and Inodes

In classical Unix file systems, a directory is simply a special type of file that contains a mapping table of filenames to inode numbers. When a user or program accesses a file by its path, the kernel traverses the directory entries to resolve the filename into its corresponding integer inode number. Once the inode number is found, the filename is no longer needed to read, write, or manage the file's data.

Because the filename lives in the directory entry rather than the inode itself, multiple filenames in the same or different directories can point to the exact same inode number. This mechanism is known as a hard link. The inode tracks how many directory entries reference it using a link count field, and the file's data blocks are only freed when this link count drops to zero and no processes have the file open.

Metadata Stored Inside an Inode

Every inode has a fixed size, typically 128 or 256 bytes depending on the file system implementation, and resides in a dedicated inode table on disk. Inside this structure, the file system records essential metadata about the object:

  • File type and permissions: Indicates whether the object is a regular file, directory, symbolic link, or device node, along with read, write, and execute bits for the owner, group, and others.
  • Ownership: Numeric user ID (UID) and group ID (GID) of the file's owner.
  • Timestamps: Creation or change time (ctime), last modification time (mtime), and last access time (atime).
  • Size and link count: The total size of the file in bytes and the number of hard links pointing to the inode.

Direct and Indirect Block Pointers

To locate the actual file contents on the storage device, an inode contains an array of block pointers. In classical Unix file systems such as the Berkeley Fast File System (FFS) or ext2, an inode typically holds 15 pointers:

  1. Direct pointers: The first 12 pointers reference data blocks directly. For small files, the kernel can read the data in a single disk lookup after reading the inode.
  2. Single indirect pointer: The 13th pointer points to a block that contains an array of block addresses, rather than file data.
  3. Double indirect pointer: The 14th pointer points to a block of pointers, each of which points to another block of pointers to data blocks.
  4. Triple indirect pointer: The 15th pointer adds a third level of indirection for very large files.

If a block size is \(B\) bytes and each block pointer is \(P\) bytes, a single indirect block can address \(\frac{B}{P}\) data blocks. Consequently, the maximum number of data blocks addressable by direct, single, double, and triple indirect pointers is:

\[N_{\text{blocks}} = 12 + \left(\frac{B}{P}\right) + \left(\frac{B}{P}\right)^2 + \left(\frac{B}{P}\right)^3\]

This hierarchical pointer design keeps the inode compact for small files while still allowing the file system to scale to large files without wasting metadata space.