Inode
An inode is a data structure in a Linux filesystem that stores metadata about a file — its permissions, owner, size, and data block locations — but not its filename. The filename lives in a directory entry that points to the inode number.
What Is an Inode in Simple Terms
Think of a library again. The inode is the library card — it contains all the information about a book (author, size, location on shelves, who can borrow it) but not the title. The title is written on a separate index card (the directory entry) that says "the book called X is at library card number 12345."
This separation is what makes hard links possible: two different titles (filenames) can point to the same library card (inode) — the same actual file content.
How It Works
Every file and directory has exactly one inode. Every inode has a unique number within its filesystem. Directory entries map filenames to inode numbers.
Directory /etc/+-------------------------+| hostname -> inode 1234 || hosts -> inode 1235 || passwd -> inode 1236 || shadow -> inode 1237 |+-------------------------+ Inode 1235 (hosts file)+-----------------------------+| Permissions: 644 || Owner UID: 0 (root) || Group GID: 0 (root) || Size: 221 bytes || Last modified: Jan 15 09:00 || Links: 1 (number of names) || Data blocks: [block 48291] |+-----------------------------+What an inode stores:
Permissions (the 10-character rwxr-xr-x string)Owner (UID number)Group (GID number)File size in bytesTimestamps: access (atime), modify (mtime), change (ctime)Link count (how many directory entries point to this inode)Pointers to data blocks on disk What it does NOT store: - The filename (that is in the directory entry) - The file content (that is in data blocks)Hard links — two names, one inode:
## Create a hard linkln /etc/hosts /tmp/hosts-hardlink ## Both names point to the same inodels -lai /etc/hosts /tmp/hosts-hardlink## 1235 -rw-r--r-- 2 root root 221 Jan 15 /etc/hosts## 1235 -rw-r--r-- 2 root root 221 Jan 15 /tmp/hosts-hardlink## Note: same inode number (1235), link count is 2 ## Modifying one modifies both (same file)echo "127.0.0.2 test" >> /tmp/hosts-hardlinkcat /etc/hosts ## shows the change ## Deleting one does not delete the datarm /tmp/hosts-hardlink ## link count drops to 1cat /etc/hosts ## still worksSymbolic links — a file that points to a name:
## Create a symbolic linkln -s /etc/hosts /tmp/hosts-symlink ## The symlink has its own inodels -lai /etc/hosts /tmp/hosts-symlink## 1235 -rw-r--r-- 1 root root 221 Jan 15 /etc/hosts## 9876 lrwxrwxrwx 1 root root 10 Jan 15 /tmp/hosts-symlink -> /etc/hosts## Different inode numbers ## Symlink stores the target path, not the contentreadlink /tmp/hosts-symlink## /etc/hosts ## If target is deleted, symlink breaksrm /etc/hostscat /tmp/hosts-symlink ## Error: No such file or directoryPractical Commands
## Show inode number with lsls -lai /etc/hosts## First column is inode number ## Show inode info with statstat /etc/hosts## File: /etc/hosts## Size: 221 Blocks: 8 IO Block: 4096 regular file## Device: 202ah/522d Inode: 1235 Links: 1## Access: (0644/-rw-r--r--) Uid: (0/root) Gid: (0/root) ## Check inode usage across filesystemdf -i## Shows IUsed and IFree per filesystem ## Find files by inode number (useful for finding hard links)find / -inum 1235 2>/dev/null ## Find files with multiple hard links (inode link count > 1)find /etc -links +1 -type fTroubleshooting
| Symptom | Command | What to Look For |
|---|---|---|
| Cannot create files, disk not full | df -i |
IUse% at 100% — inode exhaustion |
| Two files always identical | ls -lai both-files |
Same inode number = hard links |
| File deleted but disk space not freed | `lsof | grep deleted` |
| Symlink not working | readlink -f symlinkname |
Target path does not exist |
TipInode exhaustion is more common than you might expect on servers running many small files — email servers, log servers, build systems. A mailbox directory with 2 million tiny email files can exhaust inodes even when gigabytes of disk space remain. Monitor
df -ialongsidedf -h.
RememberWhen a process deletes a file, it decrements the inode link count. The disk space is only freed when the link count reaches zero AND no process has the file open. That is why
lsof | grep deletedfinds files that are deleted but still consuming disk space.
SecurityHard links cannot cross filesystem boundaries. A hard link to
/etc/shadowfrom/tmpis impossible if they are on different filesystems. This is an intentional security constraint — it prevents users from creating hard links to files they do not own.
Frequently Asked Questions
Why can a Linux filesystem run out of space for new files even when df shows free disk space?
Each filesystem allocates a fixed number of inodes at creation time, separate from data block capacity. If a workload creates millions of tiny files (a common pattern with certain caching layers or session-storage setups), you can exhaust the inode table while gigabytes of raw disk space remain free — `df -i` shows inode usage separately from `df`'s block usage, and 100% inode usage blocks all new file creation regardless of free space.
Why does a hard link not create a new inode, but a symbolic link does?
A hard link is just another directory entry pointing to the same inode number, so both names share identical permissions, ownership, and data — deleting one leaves the other intact until the inode's link count hits zero. A symlink is a separate small file with its own inode that stores a path string pointing to another file, which is why symlinks can cross filesystems and point to nonexistent targets (dangling links) in a way hard links cannot.