Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I read in text books that Unix/Linux doesn't allow hard links to directories but does allow soft links. Is it because, when we have cycles and if we create hard links, and after some time we delete the original file, it will point to some garbage value?

If cycles were the sole reason behind not allowing hard links, then why are soft links to directories allowed?

share|improve this question
Where should .. point to? Especially after removing the hard link to this directory, in the directory pointed to by ..? It needs to point somewhere. – Thorbjørn Ravn Andersen Jun 24 '13 at 22:50
.. doesn't need to physically exist on any drive. It's the operating system's job to keep track of the current working directory, anyway, so it should be relatively simple to also keep a list of inodes associated with each process' cwd and refer to that when it sees a use of ... Of course, that would mean symlinks would need to be created with that in mind, but you already have to be careful not to break symlinks, and I don't think that additional rule would render them useless. – Parthian Shot Feb 4 '15 at 17:28
up vote 100 down vote accepted

This is just a bad idea, as there is no way to tell the difference between a hard link and an original name.

Allowing hard links to directories would break the directed acyclic graph structure of the filesystem, possibly creating directory loops and dangling directory subtrees, which would make fsck and any other file tree walkers error prone.

First, to understand this, let's talk about inodes. The data in the filesystem is held in blocks on the disk, and those blocks are collected together by an inode. You can think of the inode as THE file.  Inodes lack filenames, though. That's where links come in.

A link is just a pointer to an inode. A directory is an inode that holds links. Each filename in a directory is just a link to an inode. Opening a file in Unix also creates a link, but it's a different type of link (it's not a named link).

A hard link is just an extra directory entry pointing to that inode. When you ls -l, the number after the permissions is the named link count. Most regular files will have one link. Creating a new hard link to a file will make both filenames point to the same inode. Note:

% ls -l test
ls: test: No such file or directory
% touch test
% ls -l test
-rw-r--r--  1 danny  staff  0 Oct 13 17:58 test
% ln test test2
% ls -l test*
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
% touch test3
% ls -l test*
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
-rw-r--r--  1 danny  staff  0 Oct 13 17:59 test3
            ^ this is the link count

Now, you can clearly see that there is no such thing as a hard link. A hard link is the same as a regular name. In the above example, test or test2, which is the original file and which is the hard link? By the end, you can't really tell (even by timestamps) because both names point to the same contents, the same inode:

% ls -li test*  
14445750 -rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
14445750 -rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
14445892 -rw-r--r--  1 danny  staff  0 Oct 13 17:59 test3

The -i flag to ls shows you inode numbers in the beginning of the line. Note how test and test2 have the same inode number, but test3 has a different one.

Now, if you were allowed to do this for directories, two different directories in different points in the filesystem could point to the same thing. In fact, a subdir could point back to its grandparent, creating a loop.

Why is this loop a concern? Because when you are traversing, there is no way to detect you are looping (without keeping track of inode numbers as you traverse). Imagine you are writing the du command, which needs to recurse through subdirs to find out about disk usage. How would du know when it hit a loop? It is error prone and a lot of bookkeeping that du would have to do, just to pull off this simple task.

Symlinks are a whole different beast, in that they are a special type of "file" that many file filesystem APIs tend to automatically follow. Note, a symlink can point to a nonexistent destination, because they point by name, and not directly to an inode. That concept doesn't make sense with hard links, because the mere existence of a "hard link" means the file exists.

So why can du deal with symlinks easily and not hard links? We were able to see above that hard links are indistinguishable from normal directory entries. Symlinks, however, are special, detectable, and skippable!  du notices that the symlink is a symlink, and skips it completely!

% ls -l 
total 4
drwxr-xr-x  3 danny  staff  102 Oct 13 18:14 test1/
lrwxr-xr-x  1 danny  staff    5 Oct 13 18:13 test2@ -> test1
% du -ah
242M    ./test1/bigfile
242M    ./test1
4.0K    ./test2
242M    .
share|improve this answer
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem. Can you please explain more about the problem with cycles using hard links? Why is it ok with symlinks – user3539 Oct 12 '11 at 1:13
They seem to have allowed it on Macs by adding cycle detection to the link() system call, and refusing to allow you to create a directory hard link if it would create a cycle. Seems to be a reasonable solution. – psusi Oct 14 '11 at 20:08
@psusi mkdir -p a/b; nocheckln c a; mv c a/b; -- the nocheckln there is a theoretical ln that doesnt check for directory args, and just passes to link, and because no cycle is made, we are all good in creating 'c'. then we move 'c' into 'a/b', and a cycle is created from a/b/c -> a/ -- checking in link() is not good enough – Danny Dulai Oct 15 '11 at 2:05
Upvoted for the effort, nice answer, fully explained, and easy to understand. – 2bc Mar 24 '12 at 12:48
@WhiteWinterWolf, according to this link, they specifically added support for it for time machine, but only root is allowed to do it: superuser.com/questions/360926/… – psusi Jan 23 at 16:18

With the exception of mount points, each directory has one and only parent: ...

One way to do pwd is to check the device:inode for '.' and '..'. If they are the same, you have reached the root of the file system. Otherwise, find the name of the current directory in the parent, push that on a stack, and start comparing '../.' with '../..', then '../../.' with '../../..', etc. Once you've hit the root, start popping and printing the names from the stack. This algorithm relies on the fact that each directory has one and only one parent.

If hard links to directories were allowed, which one of the multiple parents should .. point to? That is one compelling reason why hardlinks to directories are not allowed.

Symlinks to directories don't cause that problem. If a program wants to, it could do an lstat() on each part of the pathname and detect when a symlink is encountered. The pwd algorithm will return the true absolute pathname for a target directory. The fact that there is a piece of text somewhere (the symlink) that points to the target directory is pretty much irrelevant. The existence of such a symlink does not create a loop in the graph.

share|improve this answer
Not so sure about this. If we think of .. as being a sort of virtual hardlink to the parent, there is no technical reason that the target of the link can only have one other link to it. pwd would just have to use a different algorithm to resolve the path. – Benubird Mar 5 '14 at 9:44
It's not that more than one .. can point to a directory. That already happens now. In /bin, /usr, /etc the .. all point to /. The problem is that each directory only has one .. pointing out of it, and that's intentional, because the semantics of filesystems demand that from any file or directory name, there is only one path up the tree towards the root. – drg May 10 at 23:42

I like to add few more points about this question. Hard links for directories are allowed in linux, but in a restricted way.

One way we can test this is when we list the content of a directory we find two special directories "." and "..". As we know "." points to the same directory and ".." points to the parent directory.

So lets create a directory tree where "a" is the parent directory which has directory "b" as its child.

 `-- b

Note down the inode of directory "a". And when we do a ls -la from directory "a" we can see that "." directory also points to the same inode.

797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a

And here we can find that the directory "a" has three hard links. This is because the inode 797358 has three hardlinks in the name of "." inside "a" directory and name as ".." inside directory "b" and one with name "a" itslef.

$ ls -ali a/
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 .

$ ls -ali a/b/
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 ..

So here we can understand that hardlinks are there for directories only to connect with their parent and child directories. And so a directory without a child will only have 2 hardlink, and so directory "b" will have only two hardlink.

One reason why hard linking of directories freely were prevented would be to avoid infinite reference loops which will confuse programs which traverse filesystem.

As filesystem is organised as tree and as tree cannot have cyclic reference this should have been avoided.

share|improve this answer
Good example. It cleared my doubt. So these cases are handled in a special way to avoid infinite loops. right? – G Gill Oct 7 '14 at 1:42
As we have a limited way of allowing hard links for directories i.e ".." and "." we will not reach a infinite loop and so we would not require any special ways to avoid those as they will not happen :) – Kannan Mohan Oct 8 '14 at 3:20

None of the following are the real reason for disallowing hard links to directories; each problem is fairly easy to solve:

  • cycles in the tree structure cause difficult traversal
  • multiple parents, so which is the "real" one ?
  • filesystem garbage collection

The real reason (as hinted by @Thorbjørn Ravn Andersen) comes when you delete a directory which has multiple parents, from the directory pointed to by ..:

What should .. now point to ?

If the directory is deleted from its parent but its link count is still greater than 0 then there must be something, somewhere still pointing to it. You can't leave .. pointing to nothing; lots of programs rely on .., so the system would have to traverse the entire file system until it finds the first thing that points to the deleted directory, just to update ... Either that, or the file system would have to maintain a list of all directories pointing to a hard linked directory.

Either way, this would be a performance overhead and an extra complication for the file system meta data and/or code, so the designers decided not to allow it.

share|improve this answer
That's easy to solve as well: keep a list of parents of a child directory, which you update when you add or remove a link to the child. When you delete the canonical parent (the target of the child's ..), update .. to point to one of the other parents in the list. – jathd Jan 23 '15 at 19:29
I agree. Not rocket science to solve. But nonetheless a performance overhead, and it would take up a little bit extra space in the file system meta data and add complication. And so the designers went for the simple, fast approach - don't allow links to hard directories. – Lqueryvg Jan 24 '15 at 12:54
This reason is no different than other implementation challenges. The real reason is that allowing cycles would violate settled semantics and behaviors. There is exactly one path from any file/dir name back up the tree to the root, and therefore one canonical path name for every file/dir name. What is the rational behavior of rm -rf dir on a directory with multiple parents? When a program wants to know what directory it is in when referring to .., what is the correct answer? Maybe you can imagine acceptable answers to questions like these, but they aren't the Unix answers. – drg May 11 at 0:09
Sym links to dirs "violate settled semantics and behaviours", yet they are still allowed. Some commands therefore need options to control whether sym links are followed (e.g. -L in find and cp). When a program follows '..' there is further confusion, hence the difference in output from pwd and /bin/pwd after traversing a sym link. There are no "Unix answers"; just design decisions. This one revolves around what becomes of ".." as I stated in my answer. Unfortunately, '..' isn't even mentioned in the answer that everyone else is so sheepishly voting for. – Lqueryvg May 11 at 21:18
BTW, I'm not saying I'm in favour of hard links to dirs. Not at all. I don't want my day job to be harder than it is already. – Lqueryvg May 11 at 21:19

You can use bind mount to simulate hard linking directories

sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory
sudo umount /else/dummy_but_existing_directory
share|improve this answer

This is a good explanation. Regarding "Which one of the multiple parents should .. point to?" one solution would be for a process to maintain its full wd path, either as inodes or as a string. inodes would be more robust since names can be changed. At least in the olden days, there was an in-core inode for every open file that was incremented whenever a file was opened, decremented when closed. When it reached zero it and the storage it pointed to would be freed up. When the file was no longer open by anybody, it (The in-core copy) would be abandoned. This would maintain the path as valid if some other process moved a directory to another directory while the subdirectory was in the path of another process. Similar to how you can delete an open file but it is simply removed from the directory, but still open for any processes who have it open.

Hard-linking directories used to be freely allowed in Bell Labs UNIX, at least V6 and V7, Don't know about Berkeley or later. No flag required. Could you make loops? Yes, don't do that. It is very clear what you are doing if you make a loop. Nether should you practice knot tying around your neck while you are waiting for your turn to skydive out of a plane if you have the other end conveniently hung from a hook on the bulk-head.

What I hoped to do with it today was to hard-link lhome to home so that I could have /home/administ available whether or not /home was covered up with an automout over home, that automount having a symlink named administ to /lhome/administ. This enables me to have an administrative account that works regardless of the state of my primary home file system. This IS an experiment for linux, but I think learned at one time for the UCB based SunOS that automounts are done at the ascii string level. It is hard to see how they could be done otherwise as a layer on top of any arbitrary FS.

I read elsewhere that . and .. are not files any more in the directory either. I am sure that there are good reasons for all of this, and that much of what we enjoy (Such as being able to mount NTFS) is possible because of such things, but some of the elegance of UNIX was in the implementation. It is the benefits such as generality and malleability that this elegance provided that has enabled it to be so robust and to endure for four decades. As we loose the elegant implementations it will eventually become like Windows (I hope I am wrong!). Someone would then create a new OS which is based on elegant principles. Something to think about. Perhaps I am wrong, I am not (obviously) familiar with the current implementation. It is amazing though how applicable 30 year old understanding is to Linux... most of the time!

share|improve this answer
I think, though I may be wrong, that . and .. are not hardlinks in file-system, for modern file-systems. However the file-system driver fakes them. It is these file-system that stop ups hard linking directories. For old file-systems it was possible (but dangerous). To do what you are trying, look at mount --bind, see also mount --make… and maybe containers. – richard Feb 23 at 23:03

Hardlink creation on directories would be unrevertable. Suppose we have :

│  └──subfiles

I hardlink it to /dir2.

So /dir2 now also contains all these files and directories

What if I change my mind? I can't just rmdir /dir2 (because it is non empty)

And if I recursively deletes in /dir2... it will be deleted from /dir1 too!

IMHO it's a largely sufficient reason to avoid this!

share|improve this answer
That should not be a problem. With your case, when we create hardlink to dir2 we have to make hardlink to all the contents in dir1 and so if we rename or delete dir2 only an extra link to the inode gets deleted. And that should not affect dir1 and its content as there is atleast one link (dir1) to the inode. – Kannan Mohan Sep 17 '14 at 13:20

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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