How does a computer get from a file path to the actual contents of a file?
When a program asks to open a path such as /home/user/report.pdf, it may feel as if the path directly points to one stored object. From the user’s point of view, report.pdf appears as a single file that can be opened, moved, renamed, or deleted.
But the file path is not the file’s contents, and the file name is not stored inside those contents.
This article explains that chain: how a specific file path is resolved through directories, how the final name leads to metadata, and how that metadata leads to the stored contents.
This article uses a Unix-like file system model, where directory entries map names to inode numbers.
The Chain in One View
Before following /home/user/report.pdf step by step, it helps to see the main parts of the chain.
A file path does not directly contain the file’s bytes. It is resolved through a chain of file-system structures:
- File path: A user-facing way to name a file, such as
/home/user/report.pdf. It leads to a sequence of directory lookups. - Directory entry: A stored mapping from one name to one inode number. It leads to the inode number for the next file or directory.
- Inode: The metadata object identified by an inode number. It leads to metadata and content-location information.
- Content-location information: The file-system information that describes where file data is stored. It leads to logical block ranges on the backing block device.
- Lower storage layers: The OS-managed layers below the file system. They turn file-system block locations into the LBA ranges used in storage-device read/write commands.
This article focuses mainly on the file-system part of the chain: how names, directories, inode numbers, inodes, and content locations are connected. The lower storage layers matter because they explain how file-system locations eventually become read and write requests to a storage device, but they are not the main focus of the article.
Resolving a File Path
Suppose a program asks the operating system to open the file at /home/user/report.pdf.
The operating system does not jump directly from the full path to the file’s contents. It resolves the path one name at a time.
For an absolute path such as /home/user/report.pdf, resolution starts at the root directory, /. The file system looks inside that directory for the name home. That name maps to the inode number for the next directory, /home.
Then the file system looks inside /home for the name user. That name maps to the inode number for /home/user.
Finally, the file system looks inside /home/user for the name report.pdf. That final name maps to the inode number for the target file.
The steps look like this:
| Current directory | Name being looked up | Result |
|---|---|---|
/ | home | inode number for the home directory |
/home | user | inode number for the user directory |
/home/user | report.pdf | inode number for the target file |
The final result of this simplified path walk is not the file’s bytes. Conceptually, the walk has found the directory entry for report.pdf, which gives the inode number needed to identify the file’s inode. To understand why that happens, we need to look more closely at what a directory entry stores.
A Directory Stores Name-to-Inode Entries
Before looking more closely at directory entries, it helps to briefly introduce inode numbers and inodes.
Within one mounted file system, an inode number identifies an inode, and the file system uses that number to find the inode. The inode stores metadata for a file or directory, including its type, permissions, size, and content-location information. A file or directory name is stored separately in a directory entry, which maps that name to the inode number.
A directory entry is one record inside a directory’s data. It connects a visible name, such as report.pdf, to an inode number.
A directory is also a file-system object with its own inode. From the user’s point of view, it looks like a folder that contains files. Inside the file system, its directory data stores entries that map names to inode numbers.
For example, suppose the user opens the folder /home/user and sees these items:
report.pdfmemo.txtphotos
From the user’s point of view, /home/user looks like a folder that contains those objects.
Inside the file system, however, /home/user is a directory object. Its directory data stores entries that connect visible names to inode numbers. It may contain entries like this:
| Entry name | Inode number |
|---|---|
photos | 12347 |
report.pdf | 12345 |
memo.txt | 12346 |
If the entry points to a directory, such as photos, the file system can load that directory’s inode and then read that directory’s own entries. That is how path resolution continues from one directory to the next.
The directory entry for report.pdf does not contain the PDF bytes. It only says that the name report.pdf is associated with inode number 12345.
The file system then uses inode number 12345 to find the inode for report.pdf. That inode describes the file and points to the storage locations where the file’s contents are stored.
Block Devices, File Systems, and Mounting
Before looking more closely at how an inode leads to the file’s contents, it helps to define a few lower-layer terms, including block device, file system, mounting, and backing block device.
A block device is a storage-like object that the operating system can read from and write to in blocks. A disk partition, an LVM volume, a RAID device, or another virtual block device can all appear as block devices to the file system.
A file system is created on top of a block device when that block device is formatted. The file system gives the raw block storage a structure for directories, metadata, and file contents.
Mounting does not create the file system. Mounting attaches an existing file system to a directory path, such as /home, so that users and programs can access its files through normal paths.
In this article, the backing block device means the block device that provides storage for the mounted file system.
Metadata Points to File Contents
The inode does not store the file name. The name report.pdf is stored in the directory entry. The inode stores metadata about the file and information about where the file’s contents are stored.
The inode for report.pdf may contain information like this:
| Inode component | Example for report.pdf |
|---|---|
| File type | regular file |
| Permissions | rw-r--r-- |
| Owner | user id, group id |
| Size | 204,800 bytes |
| Timestamps | access time, modification time, change time |
| Link count | 1 |
| Content-location information | block pointers, extents, or another mapping structure |
| Block count | number of allocated blocks |
| Optional metadata | ACLs or extended attributes |
The exact fields depend on the file system, but the main idea is the same. The inode stores the file’s metadata and the information needed to find its contents.
The inode’s content-location information maps file offsets to file-system block ranges on the backing block device. That information may be represented with block pointers, extents, or another file-system-specific structure.
For example, suppose report.pdf is 204,800 bytes and the file system uses 4 KiB blocks. Since 4 KiB is 4,096 bytes, the file’s contents would occupy 50 file-system data blocks in this simple example.
If those blocks are stored contiguously, the content-location information might mean something like this:
| File offset range | File block range | File-system block range on the backing block device | Length |
|---|---|---|---|
0-204,799 | 0-49 | 8000-8049 | 50 file-system blocks |
This table is only a human-readable way to show the idea. The file system would store this information in its own metadata format, not as a table. The point is that the first 50 blocks of the file can be mapped to a range of file-system blocks on the backing block device.
That range is still not necessarily the final physical location on the storage media. It is the file system’s view of where the data lives on the backing block device for that mounted file system.
After any necessary mappings in the lower storage layers, such as partition, LVM, RAID, or device-mapper mappings, those logical block ranges are translated into the starting LBA and transfer length used in the final storage-device read/write command.
When the operating system sends a read or write request to a storage device, it identifies the target range using a starting LBA and a transfer length.
An LBA, or Logical Block Address, is a logical block number that a storage device exposes to the operating system. The transfer length tells the device how much data to read or write from that starting point.
What Rename, Move, and Delete Change
So far, we have followed how opening a file leads from a path to stored contents. Rename, move, and delete can also be understood by looking at which pieces change.
The separation between directory entries and inodes explains several everyday file operations.
Renaming a file usually changes a directory entry, not the file’s contents. If report.pdf becomes final-report.pdf in the same directory, the name changes, but the inode and data blocks can remain the same.
Moving a file within the same file system can also be cheap. The file system can remove a directory entry from one directory and add a directory entry in another directory that points to the same inode.
Deleting a file removes a directory entry and decreases the inode’s link count, which tracks how many directory entries still point to the inode. The file’s storage can be freed only when no directory entries and no open file handles still refer to the inode.
Conclusion
A file path does not point directly to the file’s bytes. It leads through file-system structures that connect a visible name to metadata and connect that metadata to the file’s stored contents.
A directory entry connects a name to an inode number. The inode stores metadata and content-location information. The file system uses that information to find the file’s data on the backing block device, and lower storage layers translate those locations into the LBA ranges used by the storage device.
The important idea is that the file name, the metadata, and the file contents are connected, but they are not the same thing. A file system makes them appear as one file by keeping those pieces connected through its own structures.