Author: R. Koucha
Last update: 24-Mar-2019


Hard links to make embedded file systems

more efficient



Introduction
Recap
A hard link consumes less space than a symbolic link
The access to a hard link is more efficient than the access to a symbolic link
About the author


Introduction

It is a good rule of thumb to keep embedded file systems as tiny and efficient as possible. Moreover when the target is a memory based file system or it is driven by a slow processor or the memory is space is very limited.

Replacing symbolic by hard links is one option to keep the file system as small as possible. Possible applications are the targets using busybox where all the shell excutables are linked to one executable called busybox. The "lib" directory is another typical candidate as most library names are links.

Recap


A link allows a file to appearc multiple time in the file systems.

A hard links cannot span file systems, and is actually an additional reference to a file stored in that file system. Deleting the "original" file will not remove the file until the last hard link has been removed as well (the link count equals zero).

A symbolic link is a special type of file that only stores the path to the "original" file, and this type of file can span file systems. Deleting a symbolic link will not delete the "original" file, and deleting the original file will not removed the link, but leave it "unresolved." An attempt to read an unresolved link will result in a "File Not Found" message.

Both hard links and symbolic links are created thanks to the "ln" shell command. In the latter case, we use the option "-s".

When using the "ls" shell command, it is easy to distinguish symbolic links from other files as an arrow is displayed:

> ls -l /lib
[...]
lrwxrwxrwx  1 root root      21 2007-02-08 13:17 cpp -> /etc/alternatives/cpp
drwxr-xr-x  2 root root    4096 2006-10-25 16:03 dhcp3-client
drwxr-xr-x  5 root root    4096 2007-07-21 22:12 firmware
drwxr-xr-x  3 root root    4096 2006-10-25 16:11 grub
lrwxrwxrwx  1 root root      19 2007-02-08 13:17 i386-linux-gnu -> /lib/i486-linux-gnu
drwxr-xr-x  2 root root    4096 2006-10-10 16:33 i486-linux-gnu
[...]

For hard links it is more difficult to distinguish them as we need to display its inode number and find in the file system another file name with the same inode number. In the following example, the hard links are located in the same directory. So, when we use the "-i" option of "ls", we can see that they point on the same inode:

> ls -li
total 8
2031740 -rw-r--r-- 2 koucha koucha 1 2007-08-14 12:30 bar
2031740 -rw-r--r-- 2 koucha koucha 1 2007-08-14 12:30 foo

The third columns gives the number of hard links in the inode.

A hard link consumes less space than a symbolic link

Only one inode for all the hard links to a same file: reference counter in the inode.

One inode per symbolic links: each inode points on data block where is stored the name of the target link. So, we consume one inode and potentially data blocks if the name of the target link is not stored in the inode itself (on some file systems like ext2, the name of the target link is stored in the inode itself unless the name is very long. If too long, the name is stored in the data blocks)

The access to a hard link is more efficient than the access to a symbolic link


Let's say we have the following symbolic link: /home/user/foo --> /other/bar


Each time we access the symbolic link "/home/user/foo", we implicitely search for the inode of the file "bar":
  1. Look for inode of "/" : root inode
  2. As the root inode describes a directory, look for "home" in the data blocks pointed by the root inode
  3. The entry "home" provides the inode number of the directory "home"
  4. Look for the file "foo" in the data blocks pointed by the inode of "home"
  5. The entry "foo" provides the inode number of the file "foo"
  6. foo's inode indicates that foo is a symbolic link to "/other/bar"
  7. Look for inode of "/" : root inode
  8. As the root inode describes a directory, look for "other"  in the data blocks pointed by the root inode
  9. The entry "other" provides the inode number of the directory "other"
  10. Look for the file "bar" in the data blocks pointed by the inode of "other"
  11. The entry "other" provides the inode number of the file "other"

Let's say we have the following hard link: /home/user/foo --> /other/bar


Each time we access the hard link "/home/user/foo", we implicitely search for the inode of the file "bar":
  1. Look for inode of "/" : root inode
  2. As the root inode describes a directory, look for "home" in the data blocks pointed by the root inode
  3. The entry "home" provides the inode number of the directory "home"
  4. Look for the file "foo" in the data blocks pointed by the inode of "home"
  5. The entry "foo" provides the inode number of the file "foo" which is the inode of "bar" as well

About the author

The author is an engineer in computer sciences located in France. He can be contacted here.