10

Is a directory removed when its number of hard links becomes 0?

A directory always has at least 2 as its number of hard links, because of .. When rm -r a directory, does it decrease the number of hard link from 2 to 0 by 2 instead of 1?

Can the number of hard links of a directory ever be 1?

Thanks.

9

Firstly not all filesystems use . and .. as hard links. this is documented in the gnu find manual. I am going to ignore those filesystems for the rest of my answer because they were not designed for unix and only complicate things without adding clarity. I am also going to ignore the root directory and mount points for the same reason.

the number of links to a directory is never less than two because of . and ... The number of subdirectories is equal to the number of links minus two. Because of this you cannot link or unlink a directory, so rm -r will stat a file before deleting and use rmdir instead of unlink on directories. The two system calls use completely different code paths in the kernel.

|improve this answer|||||
  • Thanks. A directory has a hard link .., only when it has a subdirectory, correct? So .. isn't always present for a directory, right? – Tim May 7 '15 at 0:44
  • .. is present in each directory that is a subdirectory. which is all but / which has one too, so all directories. – hildred May 7 '15 at 0:48
  • 1
    (1) If a directory has no subdir, the directory doesn't have a hard link .. to itself. What are the hard links to the dir? the file with the pathname, and .? (2) why do you ignore mount points? – Tim May 7 '15 at 0:55
  • If the directory is a sub-directory. the entry .. will point to the parent. As a special case the root directory link points to itself. This allows cd ..\.. and similar commands to work as expected no matter where you are. You can test with the stat command. – BillThor May 7 '15 at 1:04
  • 1
    You're correct that the link count is never less than 2, but it's not because of ... It's because of . and the name in the parent directory that points to it. The only exception is the root, which has no parent. But it has .. pointing to itself, so it also has link count = 2. – Barmar May 13 '15 at 19:52
11

Any file on a conventionally designed UNIX filesystem whose reference count (e.g. the sum of the hardlink count and the number of open file handles*) reaches 0 is removed. However, on modern UNIX systems, the rmdir system call removes an empty directory in a single operation rather than removing . and .. one-by-one.

In historical UNIX systems, however, this system call did not exist. Instead, the rmdir command was a setuid program (source code can be found here) which checked that a directory was empty (other than the special entries), and then removed .. and ., in that order, and then removed the directory itself, all with the unlink system call which only root was permitted to use on directories (hence why the command was setuid). So, on those systems, the link count of a directory would momentarily be 1 after . was removed but before the directory was removed from the parent directory, then it would be 0.

The rm command, incidentally, prevented even root from removing directories. And rm -r would call out to the rmdir command to remove directories after emptying their contents.

On these historical systems, misusing the unlink call from a program running as root, running into a race condition with rmdir or mv, or creating a file in a process whose current directory has been deleted (modern systems prevent this), could result in dangling files or directories which have a hardlink count above 0 but do not exist in the directory tree. This condition was detected by dcheck, and is still one of the checks in fsck since it remains physically possible on most filesystems.


Filesystems are, incidentally, not required to implement directories (including . and ..) as normal files that have hardlinks. On these filesystems, the hardlink count of a directory will always be reported as 0 (but of course, its existence within the parent directory qualifies for a "reference count" of 1).


The behavior of of a removed directory (e.g. when examined by a process which has it already open or has it as its current directory) and the exact meaning of the "link count" of a directory are unspecified. On Mac OS X, for example, it will report a hardlink count of 2, even though it has no real hardlinks. Even though . and .. do not appear in the listing, the directory can be opened and stat may be called with the name . or ... On Linux, the link count is 0 but . and .. likewise still work.

Mac OS X also reports the number of all files in a directory as the link count, instead of just the number of subdirectories. But it is 2 even when . and .. are gone.


*This includes normal open descriptors, memory-mapped sections (including e.g. executing binaries and shared libraries), and process current directories.

|improve this answer|||||
  • 2
    strcpy to a fixed-size array in a setuid executable... these were good times! – Andrea Corbellini May 7 '15 at 6:57
  • @AndreaCorbellini There's actually a published exploit for mkdir based on the fact that it has to do the same thing in reverse. – Random832 May 7 '15 at 13:42
  • 1
    I think I found it: securityfocus.com/archive/1/365038/2004-05-31/2004-06-06/0 :) – Andrea Corbellini May 7 '15 at 15:15
  • asking about rmdir, wouldn't removin .. remove the parent directory? – Edward Torvalds Feb 9 '16 at 14:28
  • @edwardtorvalds No, I was referring to the removal of the ".." link itself, not the parent directory it points at. – Random832 Feb 9 '16 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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