Thanks to some good Q&A around here and this page, I now understand links. I see hard links refer the same inode by a different name, and copies are different "nodes, with different names. Plus soft links have the original file name and path as their inode, so if the file is moved, the link breaks.

So, I tested what I've learnt with some file ("saluton_mondo.cpp" below), made a hard and a soft link and a copy.

jmcf125@VMUbuntu:~$ ls -lh soft hard copy s*.cpp
-rw-rw-r-- 1 jmcf125 jmcf125 205 Aŭg 27 16:10 copy
-rw-rw-r-- 2 jmcf125 jmcf125 205 Aŭg 25 13:34 hard
-rw-rw-r-- 2 jmcf125 jmcf125 205 Aŭg 25 13:34 saluton_mondo.cpp
lrwxrwxrwx 1 jmcf125 jmcf125  17 Aŭg 27 16:09 soft -> saluton_mondo.cpp

I found awkward that the hard link, however, has the same size as the original and, logically, the copy. If the hard link and the original share the same inode, that has the data, and only differ by the filename, shouldn't the hard link take only the space of its name, instead of 205 bytes? Or is that the size of the original file that ls -lh returns? But then how can I know what space does the filename take? Here it says hard links have no size. Is their file name kept alongside the original file name? Where is the file name of hard links stored?

up vote 16 down vote accepted

A file is an inode with meta data among which a list of pointers to where to find the data.

In order to be able to access a file, you have to link it to a directory (think of directories as phone directories, not folders), that is add one or more entries to one of more directories to associate a name with that file.

All those links, those file names point to the same file. There's not one that is the original and the other ones that are links. They are all access points to the same file (same inode) in the directory tree. When you get the size of the file (lstat system call), you're retrieving information (that metadata referred to above) stored in the inode, it doesn't matter which file name, which link you're using to refer to that file.

By contrast symlinks are another file (another inode) whose content is a path to the target file. Like any other file, those symlinks have to be linked to a directory (must have a name) so you can access them. You can also have several links to a symlinks, or in other words, symlinks can be given several names (in one or more directories).

$ touch a
$ ln a b
$ ln -s a c
$ ln c d
$ ls -li [a-d]
10486707 -rw-r--r-- 2 stephane stephane 0 Aug 27 17:05 a
10486707 -rw-r--r-- 2 stephane stephane 0 Aug 27 17:05 b
10502404 lrwxrwxrwx 2 stephane stephane 1 Aug 27 17:05 c -> a
10502404 lrwxrwxrwx 2 stephane stephane 1 Aug 27 17:05 d -> a

Above the file number 10486707 is a regular file. Two entries in the current directory (one with name a, one with name b) link to it. Because the link count is 2, we know there's no other name of that file in the current directory or any other directory. File number 10502404 is another file, this time of type symlink linked twice to the current directory. Its content (target) is the relative path "a".

Note that if 10502404 was linked to another directory than the current one, it would typically point to a different file depending on how it was accessed.

$ mkdir 1 2
$ echo foo > 1/a
$ echo bar > 2/a
$ ln -s a 1/b
$ ln 1/b 2/b
$ ls -lia 1 2
1:
total 92
10608644 drwxr-xr-x   2 stephane stephane  4096 Aug 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Aug 27 17:26 ../
10504186 -rw-r--r--   1 stephane stephane     4 Aug 27 17:24 a
10539259 lrwxrwxrwx   2 stephane stephane     1 Aug 27 17:26 b -> a

2:
total 92
10608674 drwxr-xr-x   2 stephane stephane  4096 Aug 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Aug 27 17:26 ../
10539044 -rw-r--r--   1 stephane stephane     4 Aug 27 17:24 a
10539259 lrwxrwxrwx   2 stephane stephane     1 Aug 27 17:26 b -> a
$ cat 1/b
foo
$ cat 2/b
bar

Files have no names associated with them other than in the directories that link them. The space taken by their names is the entries in those directories, it's accounted for in the file size/disk usage of the directories.

You'll notice that the system call to remove a file is unlink. That is, you don't remove files, you unlink them from the directories they're referenced in. Once unlinked from the last directory that had an entry to a given file, that file is then destroyed (as long as no process has it opened).

  • Ahh... Now I see. So a file called "hi" and its exact copy called "ajhĝjdmjefsjmksgskgjkmŝŭna" take exactly the same ammout of space; because their names don't count for that lstat system call that gets their size. – JMCF125 Aug 27 '13 at 16:11
  • @JMCF125, yes the size taken by their names is the entry in the corresponding directories, it's accounted in the file size of the directories. – Stéphane Chazelas Aug 27 '13 at 16:13
  • Thanks. Can you include that in your answer? Wait, I'll clarify my question first. – JMCF125 Aug 27 '13 at 16:15

The hard link is, essentially, the original file. So, the size you see reported is the size of the file being linked to. It is soft links that only take up the space of their names (kinda).

As far as the filesystem is concerned, the hard link and the original are the same thing, they point to the same inode so the same size is reported.

  • But the hard link's name must take space, correct? – JMCF125 Aug 27 '13 at 16:02
  • See @stephan's answer below, he explains it better. – terdon Aug 27 '13 at 16:04
  • 2
    @JMCF125 Yes, but that space is inside the directory. If you create enough files, you'll notice that the directory sizes increases. The size of a file doesn't include its metadata such as its name. – Gilles Aug 27 '13 at 23:00
  • @Gilles, thanks, but @Stephane has already updated his answer with that information. Also, now I think of it better, the name of / must be stored in itself, as if you do cd .. in / you stay in /. – JMCF125 Aug 28 '13 at 13:04

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.