VMware ESXi and vSphere Cluster Management
Linux Hard Links: Inodes, Link Counts, and the ln Command
Learn how Linux hard links share an inode, how to create and inspect them with ln, ls -li, and stat, and how deletion affects linked filenames.
A hard link is an additional directory entry—another filename—for an existing file. The new name and the original name both refer directly to the same inode and therefore to the same underlying file data.
The names have equal status. Linux does not mark one name as the primary or preferred name. If one name is removed, the other names can continue to access the file.
Inodes and Directory Entries
An inode is a filesystem structure containing metadata about a file and references to its data. Typical inode metadata includes permissions, ownership, timestamps, file size, and a link count.
A filename is not the file's identity by itself. A directory contains directory entries: mappings from names to inode numbers. A pathname is the location formed by walking through directories to a directory entry.
When two directory entries point to one inode, they are hard-linked names. The inode number proves that both names identify the same underlying file.
The inode's link count is the number of directory entries pointing to that inode. Creating another hard link increases the count; removing a name decreases it.
Creating a Hard Link with ln
The basic syntax is:
ln source link_name
Without the symbolic-link option, ln creates a hard link. The source is an existing file, and link_name is the new directory-entry path.
mkdir -p ~/hard-link-practice
cd ~/hard-link-practice
printf 'example content\n' > original_file.txt
ln original_file.txt hlink.lnk
The destination name must not already be in use. If it exists, ln normally refuses to replace it. Inspect an existing destination before using an overwrite option such as ln -f; replacement should be deliberate.
Verifying a Hard Link
Use ls -li to display the inode number and link count:
ls -li original_file.txt hlink.lnk
A typical result has the same first-column inode number for both entries and a link count of 2:
123456 -rw-r--r-- 2 user user 16 Aug 18 10:00 original_file.txt
123456 -rw-r--r-- 2 user user 16 Aug 18 10:00 hlink.lnk
The exact inode number, owner, timestamps, and file size will differ on your system. The important observations are the matching inode number and the shared link count.
stat provides more detailed metadata:
stat original_file.txt hlink.lnk
Look for the inode value and a field such as Links: 2. Both pathnames should report the same inode and link count.
Reading either pathname returns the same content:
cat original_file.txt
cat hlink.lnk
Shared Data and Metadata
A hard link does not make a second copy of the contents. Both names access the same data object.
printf 'changed through the original name\n' > original_file.txt
cat hlink.lnk
printf 'changed through the hard-link name\n' > hlink.lnk
cat original_file.txt
Each cat displays the latest content because both commands use the same inode and data.
Inode-level metadata is also shared. For example, changing permissions with chmod, or changing ownership when authorized, changes the metadata seen through every hard-linked pathname:
chmod 600 original_file.txt
stat original_file.txt hlink.lnk
The names themselves belong to directory entries, while file contents and most file metadata belong to the shared inode. A directory entry can have a different name or location without creating a different file.
Deletion, Unlinking, and File Lifetime
The rm command normally performs an unlink: it removes a directory entry from the directory. It does not necessarily erase the file data immediately.
ls -li original_file.txt hlink.lnk
rm original_file.txt
ls -li hlink.lnk
cat hlink.lnk
After removing original_file.txt, hlink.lnk remains usable. The inode link count falls from 2 to 1.
| Action | Visible pathnames | Expected inode link count | Data availability |
|---|---|---|---|
| Create original file | original_file.txt | 1 | Available |
| Create a hard link | original_file.txt, hlink.lnk | 2 | Available through both names |
| Remove one pathname | One name remains | 1 | Available through the remaining name |
| Remove the final pathname | None | 0 | Data is released when no process still has it open |
When the final directory entry is removed and no process has the file open, the filesystem can release the inode and data blocks. A process that already opened the file can keep using it after its last pathname is removed. In that separate case, disk space may remain in use until the process closes the file.
Hard-Link Rules and Limitations
- Same filesystem: Hard links must point to an inode in the same filesystem. Two directories that appear close in a pathname may still be on different mounted filesystems.
- Usually regular files: Hard links normally reference regular files. Linux generally prohibits ordinary users from creating hard links to directories.
- No directory cycles: Allowing arbitrary directory hard links could create cycles and violate assumptions made by filesystem traversal tools.
- Cross-filesystem failure: An inode number is meaningful only within its own filesystem, so a cross-filesystem hard link cannot be created.
To investigate filesystem boundaries, compare the source and destination:
df -T path/to/file path/to/destination-directory
findmnt -T path/to/file
If the source and destination are on different filesystems, create the link in a directory on the source filesystem or use a symbolic link when a cross-filesystem reference is needed.
Hard Links Compared with Symbolic Links
A symbolic link, or symlink, is a separate file containing a target pathname. It does not directly share the target's inode. Create one with ln -s:
printf 'shared data\n' > original_file.txt
ln original_file.txt hard-name
ln -s original_file.txt symbolic-name
ls -li original_file.txt hard-name symbolic-name
| Characteristic | Hard link | Symbolic link |
|---|---|---|
| What the link references | Directly references the existing file's inode | Stores a target pathname |
| Inode number relationship | Link and source have the same inode number | Symlink has its own inode number |
| Can cross filesystem boundaries | No | Yes, if the stored pathname resolves |
| Can normally target directories | No for ordinary users on Linux | Yes |
| After the original pathname is removed | Other hard-link names still work | It may stop resolving |
| Can become dangling | No, not because another name was removed | Yes, when its target pathname is removed or moved |
| Creation command | ln source link_name | ln -s target link_name |
Test the difference:
printf 'comparison data\n' > original_file.txt
ln original_file.txt hard-name
ln -s original_file.txt symbolic-name
rm original_file.txt
cat hard-name
cat symbolic-name
cat hard-name still reads the data. The symbolic link may produce a “No such file or directory” error because its stored target pathname no longer resolves. Such a link is called a dangling symbolic link.
Safe Operational Use
- Before deleting a file that may be linked, inspect
ls -liorstatand check the link count. - Remember that editing through any hard-linked name changes the file seen through every other name.
- Use
cpwhen you need an independent copy. A normal copy creates a separate inode, so later content changes do not affect the source. - Practice inside a temporary directory rather than a directory containing important data.
- Do not assume a filename is the only way to reach a file. Other directory entries may refer to the same inode.
Troubleshooting
Invalid cross-device link
If ln reports “Invalid cross-device link” or a similar error, the source and destination are on different filesystems. Use df -T or findmnt -T to inspect the mounts. Create a hard link on the source filesystem, or use ln -s for a cross-filesystem reference.
Destination already exists
If ln refuses the operation, a directory entry already uses the requested destination name. Choose another name or inspect the existing entry first. Use overwrite behavior only when intentionally replacing that entry.
Changes appear through both names
This is expected when the names are hard links to one inode. Use cp to create a separate inode when independent contents are required.
Hard link to a directory is refused
Linux generally disallows directory hard links to prevent directory cycles and preserve filesystem consistency. Use a symbolic link for a directory reference when appropriate.
Disk space remains after deletion
Check whether another hard-linked pathname remains by inspecting link counts. If the link count is zero but space is still held, a process may still have the file open. Tools such as lsof, where available, can help locate open deleted files.
The supposed hard link has a different inode
A different inode usually means the item was copied, a symbolic link was created, or the wrong paths were inspected. Recreate it with ln without -s, then verify both paths using ls -li.
Exam-Relevant Summary
- A hard link is an additional directory entry for an existing inode.
- Hard-linked names share one inode, one data object, and one link count.
- The original name is not inherently more important than another hard-linked name.
ln source destinationcreates a hard link;ln -s target destinationcreates a symbolic link.ls -lishows inode numbers and link counts;statprovides detailed metadata.rmunlinks a directory entry. Data remains accessible through other hard links.- Data storage is released after the final link is removed, unless an open process still holds the file.
- Hard links cannot cross filesystem boundaries and normally cannot target directories.
- A symbolic link stores a pathname, can cross filesystems, and can become dangling.