Aug 132014
 

Article by giannis_tsakiris first posted on http://www.giannistsakiris.com

A hard link is actually nothing more than a regular directory entry, which in turn can be seen as a pointer to the actual file’s data on the disk. The cool thing about hard-links is that a file can be stored once on the disk, and be linked to multiple times, from different locations/entries, without requiring to allocate extra disk space for each file instance.

But then a question arises: Given a specific file on disk, how can someone know whether it is linked to by other directory entries or not? This can be easily answered using the ls command:

giannis@zandloper:/etc$ ls -l passwd
-rw-r--r-- 1 root root 1402 2008-03-30 17:49 passwd
;

Do you ever wonder what is this small number between the file permissions and the owner in the output of ls’s long listing format (its value is usually “1″ for files, or “2″ for directories)? This number is actually the link-count of the file, when referring to a file, or the number of contained directory entries, when referring to a directory (including the . and .. entries).


So, the answer to the question “are there any other directory entries linking to this file, and if so, how many?” can be simply answered by executing ls -l for this file and checking the link-count column. If it is just 1 that means that this is the one and only instance. If it’s greater than 1 then there are other directory entries linked to that same file.

Now, imagine you find out that a file is linked to by some other directory entry. The next thing you would want to know is who is linking to that file. To figure this out you must know what all these directory entries share in common. And that is, an inode.
An inode is a data structure used internally by a (unix-like) file system to store information about a file (it can be also considered as the file’s meta-data). Every inode has a unique (in the scope of the file system) identity number. We will use this property to locate all the hard links of a file within a file system. And this is how we can do it.

By passing the -i option to the ls command we also get the inode number for a directory entry:

giannis@zandloper:/etc$ ls -i passwd
199053 passwd

In this case, the inode number for the /etc/passwd file is 199053. Now that we have the inode number we can now do the actual search for directory entries that have that same inode number. But because it would be pointless to do such a thing since we know that there are no other hard links of this file in existence (recall the link-count “1″ in the output of the previous ls -l command which states that there is only one instance of that file), I’m going to first create a hard link of the file in my home directory:

giannis@zandloper:~$ ln /etc/passwd
giannis@zandloper:~$ ls -l passwd
-rw-r--r-- 2 root root 1402 2008-03-30 17:49 passwd

Now we’re going to search the entire file system for files with inode number equal to 199053. To do so we are going to use the find command and its -inum option:

giannis@zandloper:~$ sudo find / -inum 199053
/etc/passwd
/home/giannis/passwd


Popular Posts:

Flattr this!

  3 Responses to “Counting and listing hard links on Linux”

  1. The downside to your find command is it will find inode number 199053 on every mounted filesystem. In this case, the original file is in /etc which you know is on your root filesystem, so you should use the -xdev find option to limit the search to that filesystem. Ex: find / -inum 199053 -xdev. If the original file was on another filesystem, for instance say you have /var on a different partition and the file’s under there, just have the find command start the search there, as xdev limits the search to the filesystem on which the search began. Ex: find /var -inum 163227 -xdev.

  2. You can also use the “-samefile ” option instead of the more awkward ‘-inum ‘

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*