Linux Hard Links: Inodes, Creation, and Removal
Learn how Linux hard links use shared inodes, create them with ln, verify them with ls -li, and understand removal, limitations, and symbolic links.
A hard link is an additional filename, also called a directory entry, for an existing file. The additional name does not create a second copy of the file. Instead, both names refer to the same inode and the same file data.
After a hard link exists, Linux does not treat either filename as the inherently primary or original version. The names are simply two directory entries that identify one underlying file.
How Inodes and Directory Entries Work
An inode is a filesystem record that identifies a file. It stores metadata such as permissions, ownership, timestamps, size, and pointers or references to the file's data blocks. Each inode has an inode number within its filesystem.
A directory does not normally contain the file's complete contents. Instead, a directory entry maps a name to an inode number:
original_file.txtmaps to inode 42017.hlink.lnkalso maps to inode 42017.
These two names are hard links to the same inode. The inode's link count records how many directory entries refer to it. With two names, the link count is normally 2.
This relationship can be visualized as two names pointing to one inode, with that inode pointing to one set of file data. Reading or modifying either name reaches the same underlying data.
Creating a Hard Link with ln
The basic syntax is:
ln source-path new-link-path
The existing source pathname comes first, followed by the new pathname to create. For example:
printf '%s\n' 'first version' > original_file.txt
ln original_file.txt hlink.lnk
The command creates hlink.lnk as another directory entry for the inode already used by original_file.txt. It does not duplicate the file contents.
Verifying a Hard Link with ls -li
Use ls -li to display the inode number and link count:
ls -li original_file.txt hlink.lnk
Example output:
42017 -rw-r--r-- 2 user user 14 Aug 17 10:00 hlink.lnk
42017 -rw-r--r-- 2 user user 14 Aug 17 10:00 original_file.txt
The first column is the inode number. Both entries show 42017, proving that they reference the same inode. The number 2 after the permissions is the link count: two directory entries refer to that inode.
Hard links look like ordinary filenames in a normal directory listing. Their shared inode number becomes visible when you use ls -i or ls -li.
Shared Content and Metadata
Because both names reach one inode and one data set, reading through either pathname returns the same current content:
cat original_file.txt
cat hlink.lnk
Changing the content through one pathname changes what the other pathname reads:
printf '%s\n' 'updated content' > original_file.txt
cat hlink.lnk
The output is:
updated content
You can also append through the hard-link name and read the result through the other name:
printf '%s\n' 'another line' >> hlink.lnk
cat original_file.txt
The file size and ordinary inode-level metadata are shared because there is only one inode. This includes permissions, ownership, and timestamps. Operations such as writing can update timestamps for that shared file. A hard link is therefore not an independent backup or an independent version.
Removing a Hard Link
The rm command removes a directory entry. It does not select and destroy a special “original” file:
rm original_file.txt
ls -li hlink.lnk
cat hlink.lnk
After this command, hlink.lnk still refers to the inode and its data. The link count decreases from 2 to 1, and the remaining name can still read and modify the file.
In filesystem terminology, removing a name is often called unlinking. File data is normally released when the inode's link count reaches zero, provided that no process still has the file open. If a running process has an open file descriptor, the data can remain in use even after the final directory entry is removed; storage is released after that open reference is closed.
| Operation | Names remaining | Expected link count | Can file data still be accessed? |
|---|---|---|---|
| Create initial file | 1 | 1 | Yes |
| Create a hard link | 2 | 2 | Yes, through either name |
| Remove one pathname | 1 | 1 | Yes, through the remaining name |
| Remove the final pathname | 0 | 0 | Normally no; open processes may still access it temporarily |
Users remove hard-link names one at a time. There is no special original name that must be preserved or removed first.
Hard-Link Limitations
Hard links cannot cross filesystem boundaries
A filesystem is a storage structure with its own inode namespace. A directory path is not automatically a separate filesystem: many directories can exist within one filesystem, while a mounted filesystem can begin at a particular directory path.
Hard links must be created within the same filesystem because the directory entry must refer to an inode in that filesystem. Inspect mounted filesystem boundaries with:
df -T
findmnt
If the source and destination are on different filesystems, ln typically fails with an error such as Invalid cross-device link. Use a symbolic link when a reference must cross filesystem boundaries.
Hard links normally cannot target directories
Ordinary users are generally prevented from creating hard links to directories. Allowing unrestricted directory hard links could create cycles in the directory tree, making traversal and filesystem maintenance unsafe. Hard links to regular files are the normal use case.
The target must already exist
A hard link requires an existing inode, so the source pathname must identify an existing file. It cannot be created for a missing pathname. If you need a reference that may point to a file created later, a symbolic link can store the intended pathname instead.
Hard Links Compared with Symbolic Links
A symbolic link, or symlink, is a separate filesystem object containing a pathname reference to another location. A hard link directly adds a directory entry pointing to an existing inode.
| Property | Hard link | Symbolic link |
|---|---|---|
| What is referenced | An existing inode and its data | A stored target pathname |
| Inode behavior | The names have the same inode number | The symlink has its own inode |
| Can cross filesystem boundaries | No | Yes, if the target pathname is valid |
| Effect when one original-looking name is removed | Other hard-link names continue to work | The symlink can lose its target |
| Can become dangling | No, not because another name was removed | Yes, when its target pathname no longer exists |
| Typical creation command | ln source hard-name | ln -s source symbolic-name |
How to identify it with ls | Ordinary filename; compare inode numbers with ls -i | ls -l shows an arrow such as symbolic-name -> source |
For example:
ln original_file.txt hard-name
ln -s original_file.txt symbolic-name
ls -li original_file.txt hard-name symbolic-name
If original_file.txt is removed, hard-name remains usable because it points directly to the inode. symbolic-name still stores the text original_file.txt, but that pathname no longer resolves, so the symlink becomes dangling.
Common Problems and Troubleshooting
Invalid cross-device link
Symptom: ln reports an invalid cross-device or cross-filesystem link.
Cause: The source and destination are on different filesystems.
Solution: Create the hard link in the source's filesystem, or use ln -s if a cross-filesystem reference is required.
Destination name already exists
Symptom: ln cannot create the requested link.
Cause: The destination directory entry is already occupied.
Solution: Choose an unused name. Remove or rename the existing entry only after confirming that doing so is safe.
Unexpected shared changes
Symptom: Editing one name changes the content seen through the other name.
Cause: Both names identify one inode and one content stream.
Solution: Use cp when you need an independent file copy with separate contents.
Hard link to a directory is denied
Cause: Directory hard links are normally restricted to prevent directory-tree cycles.
Solution: Link individual files, use the directory normally, or use a symbolic link when you need a directory reference.
Data remains after removing a filename
Cause: Another hard-link name may still exist, or a process may still have the file open.
Solution: Inspect link counts with ls -l or stat, check for remaining names, and consider open file descriptors when investigating disk space that has not yet been released.
Exam-Ready Summary
- A hard link is an additional directory entry for an existing inode.
- Hard-linked names have the same inode number and share the same file data.
- The inode link count equals the number of directory entries that reference it.
ln source new-namecreates a hard link;ln -screates a symbolic link.ls -liverifies hard links by showing matching inode numbers and a shared link count.rmremoves a name, not necessarily the underlying data immediately.- Data is normally reclaimed when the link count is zero and no process still has the file open.
- Hard links cannot cross filesystem boundaries and normally cannot target directories.
- A symbolic link stores a pathname, can cross filesystem boundaries, and can become dangling.
For broader context, review File Structure In Linux, Determine File Type, and Linux.