Paths, Links, and Inodes#

Concepts#

How Linux Stores Files — Inodes#

To understand links, you first need to understand how Linux actually stores files.

Every file on a Linux filesystem has two parts:

  1. The data — the actual content of the file (bytes on disk).
  2. The inode (index node) — a data structure that stores metadata about the file:
    • File type (regular file, directory, symlink, etc.)
    • Permissions (read, write, execute)
    • Owner and group
    • File size
    • Timestamps (created, modified, accessed)
    • Pointers to the disk blocks where the data is stored
    • Link count — how many names point to this inode

Notice what the inode does not contain: the filename. The filename is stored in the directory that contains the file. A directory is essentially a table mapping names to inode numbers.

Directory entry:     filename → inode number
Inode:               metadata + pointers to data blocks
Data blocks:         actual file content

You can see a file’s inode number with:

ls -i filename
stat filename

A hard link is an additional name (directory entry) that points to the same inode. The file has one set of data and one inode, but multiple names.

# Create a file
echo "Hello" > original.txt

# Create a hard link
ln original.txt hardlink.txt

Now original.txt and hardlink.txt are two names for the exact same file:

ls -li original.txt hardlink.txt
# Same inode number, same size, link count = 2
Directory:
  original.txt  → inode 12345
  hardlink.txt  → inode 12345   (same inode!)

Inode 12345:
  data: "Hello"
  link count: 2

Key properties of hard links:

  • Same inode: both names point to the same data. Editing one changes both.
  • No “original”: after creating a hard link, neither name is more “real” than the other. Deleting one does not affect the other.
  • Link count: the inode tracks how many names point to it. Data is only deleted when the link count reaches 0 (all names are removed).
  • Cannot cross filesystems: a hard link must be on the same filesystem as the target (because inode numbers are per-filesystem).
  • Cannot link to directories: hard links to directories are not allowed (to prevent loops in the filesystem tree).

A symbolic link (symlink or soft link) is a special file that contains the path to another file. It is a pointer by name, not by inode.

# Create a symlink
ln -s /home/kmiguel/Documents/report.txt ~/Desktop/report-link
Directory:
  report-link  → inode 99999 (a different inode!)

Inode 99999:
  type: symlink
  data: "/home/kmiguel/Documents/report.txt"   (the path, stored as text)

Key properties of symlinks:

  • Different inode: the symlink is its own file, containing the path to the target.
  • Can cross filesystems: since they store a path (text), they work across different disks and partitions.
  • Can link to directories: no restriction.
  • Can break: if the target file is moved or deleted, the symlink becomes a “dangling” link (points to nothing). It still exists but cannot be followed.
  • Permissions are irrelevant: symlink permissions are always lrwxrwxrwx. Access depends on the target’s permissions.
  • Visible in ls -l: shown with -> pointing to the target.
ls -l ~/Desktop/report-link
# lrwxrwxrwx 1 kmiguel kmiguel 42 Oct 15 12:00 report-link -> /home/kmiguel/Documents/report.txt
Feature Hard Link Symbolic Link
Same inode as target Yes No (has its own inode)
Survives if target is deleted Yes (data persists) No (becomes dangling)
Cross filesystem No Yes
Link to directories No Yes
Shows in ls -l No special indicator Arrow -> to target
Created with ln target link ln -s target link

In practice, symlinks are far more common because of their flexibility. Hard links are used in specific situations (backups, package management internals).

# Show inode numbers
ls -i

# Detailed file information including inode
stat filename

# Find all hard links to a file (by inode number)
find / -inum 12345 2>/dev/null

# Find broken symlinks
find /path -xtype l

Symlinks can store either absolute or relative paths:

# Absolute symlink — always works regardless of the symlink's location
ln -s /home/kmiguel/Documents/report.txt ~/Desktop/report-link

# Relative symlink — relative to the symlink's location
cd ~/Desktop
ln -s ../Documents/report.txt report-link

Relative symlinks are portable (they still work if the whole directory tree is moved), but absolute symlinks are easier to understand and debug.


Lab#

Exercise 1: Examine Inodes#

mkdir -p ~/lab/links
cd ~/lab/links

# Create a file
echo "This is the original file" > original.txt

# See its inode number
ls -i original.txt

# Get detailed inode information
stat original.txt
# Note: Inode number, Links count (should be 1), Size, Timestamps
# Create a hard link
ln original.txt hardlink.txt

# Compare inode numbers — they should be identical
ls -li original.txt hardlink.txt

# Check link count — should be 2 for both
stat original.txt | grep Links
stat hardlink.txt | grep Links

# Modify through one name, see the change through the other
echo "Added a line" >> hardlink.txt
cat original.txt
# You should see "Added a line" — both names share the same data

# Delete the original — the data survives
rm original.txt
cat hardlink.txt
# Still works! Link count is now 1.

# Verify
stat hardlink.txt | grep Links
# Create a new file
echo "Symlink target content" > target.txt

# Create a symlink
ln -s target.txt mylink

# Examine the symlink
ls -l mylink
# Shows: mylink -> target.txt

# Different inode numbers
ls -i target.txt mylink

# Read through the symlink
cat mylink
# Shows the content of target.txt

# Delete the target — the symlink breaks
rm target.txt
ls -l mylink
# Still shows mylink -> target.txt, but in red (broken link)

cat mylink
# Error: No such file or directory

# Recreate the target — the symlink works again
echo "Recreated content" > target.txt
cat mylink
# Works!
# Create a directory with files
mkdir -p ~/lab/links/mydata
echo "file inside mydata" > ~/lab/links/mydata/info.txt

# Create a symlink to the directory
ln -s ~/lab/links/mydata ~/lab/links/data-shortcut

# Navigate through the symlink
ls ~/lab/links/data-shortcut/
cat ~/lab/links/data-shortcut/info.txt

# The symlink behaves like the directory itself
cd ~/lab/links/data-shortcut
pwd
# Note: might show the symlink path or the real path depending on the shell
pwd -P
# Shows the real (physical) path, resolving all symlinks
# The usr-merge symlinks
ls -la /bin
ls -la /sbin
ls -la /lib

# Common symlinks in /etc
ls -la /etc/alternatives/ | head -10
# The alternatives system uses symlinks to manage default commands

# Python symlinks
ls -la /usr/bin/python3
cd ~/lab/links

# Try to hard link to a directory (fails)
mkdir testdir
ln testdir testdir-hardlink
# Error: hard link not allowed for directory

# Try to hard link across filesystems (fails if /tmp is a separate filesystem)
echo "test" > /tmp/crossfs.txt
ln /tmp/crossfs.txt ~/lab/links/crossfs-hardlink
# May fail with: Invalid cross-device link

# Clean up
rm -f /tmp/crossfs.txt
rmdir testdir

Review#

1. What is an inode?

An inode is a data structure on the filesystem that stores metadata about a file: type, permissions, owner, group, size, timestamps, and pointers to the data blocks on disk. Every file has exactly one inode. The filename is NOT stored in the inode — it is stored in the directory entry.

2. What is a hard link?

A hard link is an additional directory entry (name) that points to the same inode as an existing file. Both names share the same data and metadata. Neither is the “original” — they are equal. Deleting one does not affect the other; data is only freed when the last link is removed.

3. What is a symbolic link?

A symbolic link is a special file that contains the path (as text) to another file or directory. It has its own inode, separate from the target. If the target is deleted or moved, the symlink becomes “dangling” (broken).

4. Can you create a hard link to a directory? Why or why not?

No. Hard links to directories are not allowed because they could create loops in the filesystem tree, making it impossible to traverse reliably.

5. What happens when you delete the target of a symlink vs a hard link?

Symlink: the link becomes broken (“dangling”) — it still exists but points to nothing. Hard link: nothing happens to the other hard link(s) — the data persists as long as at least one link remains. Data is only freed when the link count drops to 0.

6. How do you see a file's inode number?

ls -i filename shows the inode number alongside the name. stat filename shows the inode number along with all other metadata.

7. Why can hard links not cross filesystem boundaries?

Because inode numbers are unique only within a single filesystem. A hard link is a reference to an inode number — that number has no meaning on a different filesystem.


Previous: Filesystem Hierarchy | Next: File Permissions