Inodes: The Hidden Metadata That Powers Every File

Understand Linux inodes - the metadata structures behind every file. Learn about hard links, soft links, and inode limits.

15 min|linuxfilesystemsstoragemetadata
Best viewed on desktop for optimal interactive experience

What is an Inode?

Imagine you're in a massive library with millions of books. Each book has a unique catalog card that tells you everything about it—its size, location, when it was added, who can read it—everything except the book's title and its actual content. That catalog card is what an inode is to your files!

An inode (short for "index node") is the unsung hero of Unix filesystems. It's a tiny data structure that stores all the metadata about a file—permissions, ownership, timestamps, and most crucially, where to find the actual data on disk. Surprisingly, it doesn't store the filename itself. That's kept separately in directories, which are just special files that map names to inode numbers.

The Inode Number is the True Identity: A filename is just a human-friendly label. The inode number is what the kernel actually uses to identify a file. You could have the same data accessible via ten different names—they'd all point to the same inode.

The Inode Paradox: Running Out With Space Left

Here's something that blows people's minds: You can run out of space for new files even when your disk has gigabytes free! How? Because you've run out of inodes.

Most filesystems pre-allocate a fixed number of inodes when formatted. Use them all up (usually with millions of tiny files), and you can't create new files regardless of free space.

# Check your inode usage - you might be surprised! df -i # Output might show: Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 1310720 589824 720896 46% / # That's 589,824 files on your root partition!

The Three-Part File Structure

Before diving into inodes specifically, it's crucial to understand that Unix files have three separate components. This separation is what enables powerful features like hard links.

The Three Components of a File

The Three Components of a FileFilename"document.txt"Directory Entrypoints toInode(Inode #12345)• File type• Permissions• Owner (UID)• Group (GID)• File size• Timestamps• Link count• Data block pointers• ...points toData BlocksBlock 1024: "Hello..."Block 1025: "World..."Block 1026: "More..."Actual file contentKey Insight: The filename is NOT stored in the inode!The directory maps name → inode number, inode maps to data

Critical Concept

In Unix, a file has three parts:

  1. Filename (stored in directory) → human-readable name
  2. Inode (metadata) → everything about the file except name and data
  3. Data blocks (content) → the actual file contents

The filename and inode are separate! This enables hard links (multiple names for one inode).

What's Inside an Inode?

An inode is typically 128 or 256 bytes packed with information. Let's explore its structure:

Anatomy of an Inode

Inode #524312
Type:Regular File
Permissions:rw-r--r--
Owner:1000:1000
Size:1.00 MB
Links:2
Timestamps
Access Time (atime):
2024-01-15 10:30:00
Modify Time (mtime):
2024-01-15 09:15:00
Change Time (ctime):
2024-01-15 09:15:00
Memory Layout (128 bytes typical)
mode
uid
gid
size
atime
mtime
ctime
blocks

Key Insights

Inodes don't store filenames - directories map names to inode numbers
Hard links share the same inode, soft links have their own
Most filesystems pre-allocate inodes at format time
Running out of inodes means no new files, even with free space

The Inode Structure in Code

struct inode { uint16_t i_mode; // File type and permissions (rwxrwxrwx) uint16_t i_uid; // User ID of owner uint32_t i_size; // Size in bytes uint32_t i_atime; // Access time (last read) uint32_t i_ctime; // Change time (metadata modified) uint32_t i_mtime; // Modification time (content modified) uint32_t i_dtime; // Deletion time (0 if not deleted) uint16_t i_gid; // Group ID of owner uint16_t i_links_count; // How many hard links point here uint32_t i_blocks; // Number of 512-byte blocks allocated uint32_t i_flags; // File flags (immutable, append-only, etc.) uint32_t i_block[15]; // Pointers to data blocks (the magic!) };

The 15-Pointer Trick: How Inodes Handle Any File Size

The most clever part of an inode is its 15 block pointers in i_block[15]. This design lets a tiny 256-byte structure address files from 1 byte to multiple terabytes:

  • Pointers 0-11 (Direct): Point directly to data blocks
  • Pointer 12 (Single Indirect): Points to a block of pointers
  • Pointer 13 (Double Indirect): Points to pointers to pointers
  • Pointer 14 (Triple Indirect): Three levels deep

Block Pointer Traversal

See how the filesystem finds byte N in a file

File Offset24 KB
048KB4MB4GB5TB
Direct Block
Disk Reads:1
Inode
i_block[6]
Data Block
Block #1006

Direct access! No indirection needed. This is why small files are blazing fast.

0 - 48KB
Direct
1 disk read
48KB - 4MB
Single Indirect
2 disk reads
4MB - 4GB
Double Indirect
3 disk reads
4GB - 4TB
Triple Indirect
4 disk reads

This elegant hierarchy means:

  • Small files are blazing fast — most files are under 48KB and need only direct block access
  • Large files work — without redesigning the structure
  • No wasted space — small files don't allocate unused indirect blocks

Understanding inodes reveals why hard and soft links behave so differently. The difference comes down to what they store: an inode number vs a path string.

Hard Link vs Soft Link

What happens when you delete the original file?

Hard Link

Initial State
/home/alice/original.txt
→ inode 12345
/backup/hardlink.txt
→ inode 12345
Inode #12345
Link count: 2
Data: "Hello World"
Both Work

Both names point to the same inode. They are completely equal - neither is "the original".

Soft (Symbolic) Link

Initial State
/home/alice/original.txt
→ inode 12345
/backup/symlink.txt
→ inode 67890
Inode #67890 (symlink)
Stores path, not data
"/home/alice/original.txt"
Both Work

Symlink stores the path "/home/alice/original.txt". When accessed, the kernel follows this path.

The Fundamental Difference

Hard

Points to the inode number. Multiple names for the same underlying data. All names are equal - there is no "original".

Soft

Points to a file path. A separate file that contains a string. If the target path is deleted or moved, the link breaks.

A hard link creates another directory entry pointing to the same inode:

# Create a file and a hard link echo "Hello World" > original.txt ln original.txt hardlink.txt # Check their inodes - they're identical! ls -i original.txt hardlink.txt # 524312 original.txt # 524312 hardlink.txt # Same inode number! # The inode's link count increases stat original.txt | grep Links # Links: 2 # Delete original - hardlink still works! rm original.txt cat hardlink.txt # Still outputs "Hello World"

Allowing hard links to directories would create cycles in the filesystem tree. If /a could hard-link to /a/b/c, then cd /a/b/c/a/b/c/a/b/c... would loop forever. The kernel prevents this—only . and .. are special-cased directory hard links.

A symbolic link is a special file with its own inode that contains a path:

# Create a symbolic link ln -s original.txt symlink.txt # Check inodes - they're different ls -i original.txt symlink.txt # 524312 original.txt # 524445 symlink.txt # Different inode! # The symlink stores a path, not data readlink symlink.txt # original.txt # Delete original - symlink breaks! rm original.txt cat symlink.txt # Error: No such file or directory

Files aren't deleted when you rm them—they're deleted when the link count reaches zero. Experiment with this interactive demo:

Link Count State Machine

Discover when files actually get deleted

Inode #12345
Link Count:1
Data Blocks
#1024
#1025
#1026

Protected while link count > 0

Names pointing to this inode:

/home/alice/report.txt

→ inode 12345

Single Link - Vulnerable

This is the only name pointing to the file. Remove it and the file data is deleted forever.

Key Concept: In Unix filesystems, deleting a file name (with rm) only decrements the link count. The actual data is only freed when the link count reaches zero and no processes have the file open.

See how multiple directory entries can point to the same inode, sharing the same data:

Hard Links: Multiple Names, One Inode

Hard Links: Multiple Names, One Inode/home/alicereport.txt→ 12345photo.jpg→ 12346backup.txt→ 12345/home/bobnotes.txt→ 45678shared.txt→ 12345Inode #12345Link count: 3Type: Regular fileSize: 4096 bytesOwner: alice (1000)Permissions: -rw-r--r--Data blocks: 1024, 1025mtime: 2025-01-15 10:30Shared Data Blocks"This is the file content..."All three names point to same inode → same metadata, same data, same file!

How Hard Links Work

  • Multiple directory entries point to the same inode
  • All links share the same metadata and data
  • Link count tracks how many names exist
  • File is deleted only when link count reaches 0

Hard Link Restrictions

  • Cannot cross filesystem boundaries
  • Cannot link to directories (except . and ..)
  • Both names must be on same partition
  • Different filesystems have different inode tables
# Create a hard link
$ ln report.txt backup.txt
# Check link count
$ ls -li report.txt backup.txt
12345 -rw-r--r-- 2 alice alice 4096 Jan 15 10:30 report.txt
12345 -rw-r--r-- 2 alice alice 4096 Jan 15 10:30 backup.txt
↑ same inode ↑ link count = 2
# Delete one - file still exists!
$ rm report.txt
$ ls -li backup.txt
12345 -rw-r--r-- 1 alice alice 4096 Jan 15 10:30 backup.txt
↑ link count decreased to 1

Hard Links vs Soft Links Summary

Hard Links

  • ✓ Share the same inode
  • ✓ Can't break (until all links deleted)
  • ✓ Must be on same filesystem
  • ✗ Can't link directories
  • ✗ Can't cross filesystem boundaries

Soft/Symbolic Links

  • ✓ Have their own inode
  • ✓ Can link directories
  • ✓ Can cross filesystems
  • ✗ Can break if target moves/deletes
  • ✗ Slightly slower (extra indirection)

Path Resolution: Walking the Inode Chain

When you access a file like /home/alice/report.txt, the kernel performs a step-by-step path resolution, looking up inodes at each directory level:

Path Resolution Process

How the kernel resolves /home/alice/document.txt

Step 1 of 5
/
/home
/home/alice
inode 12345
Data
1

Start at root (inode 2)

Lookup "home" in root directory

Found: inode 1000

Complete Resolution Path

1.
Start at root (inode 2)← Current
2.
Read /home (inode 1000)
3.
Read /home/alice (inode 5678)
4.
Read inode 12345
5.
Read data blocks

Performance Note: Each step requires reading from disk. This is why path caching (dentry cache) is crucial for performance. The kernel caches directory entries to avoid repeated lookups for frequently accessed paths.

Where Inodes Live on Disk

Understanding the physical layout of a filesystem helps explain inode limitations:

Filesystem Layout on Disk

Filesystem Layout on DiskPhysical DiskBootBlockFirst sectorBoot loaderSuper-block• Filesystem info• Block size• Total inodes• Free inodesInode TableInode 1 (reserved)Inode 2 (root dir /)Inode 3Inode 4...Inode NFixed size atformat time!Data BlocksBlock 0: Directory dataBlock 1: File dataBlock 2: File data...Block N: File dataMajority ofdisk space

Boot Block

First sector containing bootloader code. Used during system startup to load the OS kernel.

Superblock

Critical filesystem metadata: block size, total blocks, free blocks, inode counts, and filesystem type.

Inode Table

Fixed-size array of inodes. Each inode stores file metadata. Size determined at format time.

Data Blocks

Actual file and directory content. Takes up the majority of disk space. Pointed to by inodes.

⚠️Inode Exhaustion Problem

You can run out of inodes even if you have free disk space! This happens when you create many small files.

$ df -i Filesystem Inodes IUsed IFree IUse% /dev/sda1 1000000 200000 800000 20% # If you hit 100% inodes, you can't create new files even with free space!

Format-Time Decisions

More inodes for many small files:
mkfs.ext4 -i 4096 /dev/sdb1

One inode per 4KB (vs default 16KB)

Fewer inodes for large media files:
mkfs.ext4 -i 65536 /dev/sdb1

One inode per 64KB

Practical Inode Commands

Finding Files by Inode

# Find inode number ls -i myfile.txt # 524312 myfile.txt # Find file by inode number find / -inum 524312 2>/dev/null # Delete a file with a weird name using inode find . -inum 524312 -delete

Diagnosing the "No Space Left" Mystery

# Disk shows space available df -h # /dev/sda1 20G 15G 4.0G 80% / # But can't create files! touch newfile # touch: cannot touch 'newfile': No space left on device # The culprit: out of inodes! df -i # /dev/sda1 1310720 1310720 0 100% / # Find the inode hogs for dir in /*; do echo "$dir: $(find $dir 2>/dev/null | wc -l)" done | sort -t: -k2 -n | tail -5

Inode Optimization at Format Time

# Format with more inodes for many small files mkfs.ext4 -i 4096 /dev/sdb1 # One inode per 4KB # Or fewer inodes for large media files mkfs.ext4 -i 65536 /dev/sdb1 # One inode per 64KB # Check current inode ratio dumpe2fs /dev/sda1 | grep "Inode size"

File Attributes Beyond Basic Permissions

Inodes store special attributes that provide powerful features:

# Make file immutable (even root can't modify!) sudo chattr +i important.conf lsattr important.conf # ----i--------e-- important.conf # Append-only (great for logs) sudo chattr +a logfile.log # Remove the attribute sudo chattr -i important.conf

The Inode Cache: Speed Magic

Linux caches recently accessed inodes in RAM for blazing-fast repeated access:

# View inode cache statistics cat /proc/slabinfo | grep inode # inode_cache 45892 45892 608 26 4 : tunables 0 0 0 # That's ~46K inodes cached in memory!

Filesystem-Specific Inode Features

Different filesystems handle inodes differently:

FilesystemInode AllocationInode SizeSpecial Features
ext4Fixed at format256 bytesExtended attributes in inode
BtrfsDynamicVariablePart of B-tree structure
XFSDynamic256-512 bytes64-bit inode numbers, clustering
ZFSDynamicVariableIntegrated with data checksums

Key Takeaways

Essential Inode Knowledge

• Identity Crisis: Inodes have numbers, not names

• Metadata Central: Everything about a file except name and data

• Limited Resource: Can run out even with free space

• Hard Links: Multiple names, same inode

• Soft Links: Separate inode pointing to a path

• Block Pointers: Clever hierarchy handles any file size

• Performance Key: Cached inodes = fast file access

• Filesystem Specific: Each filesystem handles inodes differently

Inodes are the invisible foundation of Unix filesystems—every file operation ultimately comes down to reading, writing, or modifying these tiny metadata structures. Understanding inodes transforms mysterious filesystem behaviors into logical consequences of elegant design.

Further Reading

If you found this explanation helpful, consider sharing it with others.

Mastodon