How Linux Resolves File Paths Using Hard Links

In the Linux operating system, file path resolution is the core mechanism that translates a human-readable path string into the underlying data stored on a physical disk. Hard links are central to this design because Linux completely decouples a file’s identity and data from its name. This article explains the underlying mechanisms of Linux path resolution, detailing how the Virtual File System (VFS), directory entries, and inodes interact to resolve paths using hard links.

The Foundation: Inodes and Directory Entries

To understand path resolution, you must separate a file's name from its contents:

A hard link is simply a directory entry that points directly to an existing inode. Because every standard file entry in a directory is a mapping of a name to an inode, all regular files in Linux are essentially hard links.

Step-by-Step Path Resolution

When a process initiates a system call (such as open(), stat(), or execve()) with a file path like /home/user/document.txt, the Linux kernel’s Virtual File System (VFS) resolves the path component by component:

  1. Determining the Starting Point:

    • If the path begins with a forward slash (/), resolution starts at the root directory inode (defined by the process's root filesystem namespace).
    • If the path does not begin with a slash, resolution begins at the inode corresponding to the current working directory (cwd) of the calling process.
  2. Iterative Component Lookup: The kernel splits the path by the / delimiter and processes each token sequentially:

    • It checks the permissions of the current directory inode to verify the process has execute (+x) permissions, which are required for traversal.
    • The kernel consults the directory’s entry list to find a match for the target component string.
    • Once matched, the kernel retrieves the corresponding inode number associated with that entry.
  3. Kernel Optimization via Dcache: Reading directory blocks from disk repeatedly is computationally expensive. Linux maintains a memory cache called the Directory Cache (dcache). The dcache holds dentry structures representing recently accessed path components. During resolution, the kernel looks up names in the dcache first; only on a cache miss does it read the directory contents from the storage device.

  4. Reaching the Final Target: The kernel repeats this lookup process for each subfolder until it evaluates the final token (document.txt). The final lookup extracts the target inode number, reads the inode metadata into memory, and makes the file's data blocks accessible to the process.

When you create a hard link using the command ln source.txt link.txt, the kernel creates a new directory entry (link.txt) pointing to the exact same inode number as source.txt. It also increments the reference counter (i_nlink) inside that inode.

During path resolution:

Filesystem Boundaries

Because hard links rely on raw inode numbers, they cannot cross filesystem boundaries. Inode numbers are only unique within a single filesystem instance. If a path resolution attempt requires bridging different storage devices or partitions, the operating system relies on mount points and symbolic links rather than hard links.