54

Say I just create directory newDirectory and then I do ls -ld command. I see that the number of hard links is 2. What exactly makes the hard link 2 from the start? Also is the number of subdirectories in the current directory equal to the number of hard links - 2?

John
  • 3,599
  • Extremely similar or related questions: http://unix.stackexchange.com/questions/22664/why-is-a-hard-link-in-unix, http://unix.stackexchange.com/questions/22664/why-is-a-hard-link-in-unix, http://unix.stackexchange.com/questions/21847/when-you-type-ls-a-what-is-the-significance-of-and –  Nov 17 '13 at 23:30

3 Answers3

64

Historically, the first Unix filesystem created two entries in every directory: . pointing to the directory itself, and .. pointing to its parent. This provided an easy way to traverse the filesystem, both for applications and for the OS itself.

Thus each directory has a link count of 2+n where n is the number of subdirectories. The links are the entry for that directory in its parent, the directory's own . entry, and the .. entry in each subdirectory. For example, suppose this is the content of the subtree rooted at /parent, all directories:

/parent
/parent/dir
/parent/dir/sub1
/parent/dir/sub2
/parent/dir/sub3

Then dir has a link count of 5: the dir entry in /parent, the . entry in /parent/dir, and the three .. entries in each of /parent/dir/sub1, /parent/dir/sub2 and /parent/dir/sub3. Since /parent/dir/sub1 has no subdirectory, its link count is 2 (the sub1 entry in /parent/dir and the . entry in /parent/dir/sub1).

To minimize the amount of special-casing for the root directory, which doesn't have a “proper” parent, the root directory contains a .. entry pointing to itself. This way it, too, has a link count of 2 plus the number of subdirectories, the 2 being /. and /...

Later filesystems have tended to keep track of parent directories in memory and usually don't need . and .. to exist as actual entries; typical modern unix systems treat . and .. as special values as part of the filesystem-type-independent filesystem code. Some filesystems still include . and .. entries, or pretend to even though nothing appears on the disk.

Note that even when the filesystem itself contains a .. entry, the kernel still has to handle one special case. In the root directory of a mounted filesystem, the entry called .. points to the directory itself: if the root directory is inode 2, then both the . and .. entries in the root directory point to inode 2. But accessing .. from that directory must in fact access the parent directory of the mount point, unless the mount point is /. That is, assuming /media/foo is a mount point, /media/foo/.. must designate /media, not /media/foo, even though the .. entry in the root of the filesystem mounted at /media/foo points to inode 2.

Most filesystems still report a link count of 2+n for directories regardless of whether . and .. entries exist, but there are exceptions, for example btrfs doesn't do this and changing this has been marked as a rejected idea in the btrfs wiki.

  • 8
    .. pointing to the parent doesn't affect the link count of the current directory. The count of 2 comes from . and the directory's (original) name listing itself. The way you put it is a little ambiguous, and makes it sound like . and .. are the two. .. should be used only to explain how the math works out to 2+n :) – th3an0maly Jun 21 '16 at 16:52
  • 1
    @th3an0maly Pointing to the parent affects the link count of the parent. I really don't see how “the .. entry in each subdirectory” is ambiguous, and I don't understand what you mean by “the directory's name listing itself”. – Gilles 'SO- stop being evil' Jun 21 '16 at 17:42
  • Actually, this answer: http://unix.stackexchange.com/a/101516/160264 is exactly what I've been hinting at. Read it after I read your answer, since yours was the one at the top. – th3an0maly Jun 21 '16 at 18:22
  • 1
    @th3an0maly I still have no idea what you're hinting at. Could you express it clearly, instead of hinting? – Gilles 'SO- stop being evil' Jun 21 '16 at 18:42
  • 1
    @goldilocks's answer is clear. What I meant to say is that your answer could be more like his. But then I hadn't read his answer when I was reading your answer. The first line is exactly what my original comment said: "There's one for the directory itself, and one for . inside it.". If it's still unclear to you, I'm very sorry I'm unable to clarify any further. All I could do better is copy+paste his answer here in comments. – th3an0maly Jun 21 '16 at 18:54
  • Agree that this answer was ambiguous for the actual question (although informative with regard to the extra information). The point is that the directory itself (the place where it has a name, e.g. "subdirectory", residing in its parent) is the first entry, and then the "." within itself (that is, the "." within "subdirectory") is the second. (This should mean that "/" lack the first, as it has no parent to be named in) – stolsvik Sep 08 '17 at 05:53
  • 1
    @stolsvik / doesn't have a “proper” parent, but its own .. points to itself, so its link count is 2 + number of subdirectories like any other directory. And sorry, but I still don't see the ambiguity. But I'll add an example. – Gilles 'SO- stop being evil' Sep 08 '17 at 17:08
  • The ambiguity is that there is no need to link to itself "." inside itself. – Josef Klimuk Aug 11 '20 at 14:35
15

There's one for the directory itself, and one for . inside it.

Also is the number of subdirectories in the current directory equal to the number of hard links - 2?

That makes sense, since each subdirectory creates a .. hardlink, and beyond that you can't create hardlinks to directories.1 However, I would't trust this for anything serious, esp. since it is easy to count the subdirectories and get the real number.

If you are just looking at ls output for an idea of how many subs there are, then it does give you a decent idea.

1 Or at least, you can't with ln. I have not tried to programmatically, and man 2 link is ambiguous -- there's no obvious error for linking to a directory, although there are a couple that might apply (EMLINK, EPERM). So unless there's some standard somewhere that says the only possible hard links to a directory are . and .., again, I would only treat that hard link count as a casual clue.

goldilocks
  • 87,661
  • 30
  • 204
  • 262
  • 2
    Whether links to directories are allowed, and whether you can count subdirs from the link count, are both dependent on which filesystem you're using - some allow, some don't. – alanc Nov 17 '13 at 19:07
  • 1
    Note that macOS's Time Machine actually hardlinks directories to previous backups; that way they can pretend that each incremental backup is a full copy, and they can delete any of the incrementals without impacting the others. It is also very brittle, I was playing with it using regular syscalls and I thoroughly hosed my filesystem. – w00t Apr 10 '17 at 14:36
2

This depends on the filesystem. BTRFS breaks with this convention.

# dd if=/dev/zero of=btrfs.img bs=114294784 count=1
1+0 records in
1+0 records out
114294784 bytes (114 MB, 109 MiB) copied, 0.172979 s, 661 MB/s
# mkfs.btrfs btrfs.img 
btrfs-progs v4.20.1 
See http://btrfs.wiki.kernel.org for more information.

Label: (null) UUID: ad5f6c58-ec7a-41db-9d19-ec98db96d725 Node size: 16384 Sector size: 4096 Filesystem size: 109.00MiB Block group profiles: Data: single 8.00MiB Metadata: DUP 32.00MiB System: DUP 8.00MiB SSD detected: no Incompat features: extref, skinny-metadata Number of devices: 1 Devices: ID SIZE PATH 1 109.00MiB btrfs.img

# mount btrfs.img /mnt
# mkdir -p /mnt/{1,2,3}/{1,2,3}
# find /mnt/ -links 2
# find /mnt/ -links 1
/mnt/
/mnt/1
/mnt/1/1
/mnt/1/2
/mnt/1/3
/mnt/2
/mnt/2/1
/mnt/2/2
/mnt/2/3
/mnt/3
/mnt/3/1
/mnt/3/2
/mnt/3/3

The links counter has no meaning for directories on a BTRFS:

# find /mnt/ -printf '%n %p\n'
1 /mnt/
1 /mnt/1
1 /mnt/1/1
1 /mnt/1/2
1 /mnt/1/3
1 /mnt/2
1 /mnt/2/1
1 /mnt/2/2
1 /mnt/2/3
1 /mnt/3
1 /mnt/3/1
1 /mnt/3/2
1 /mnt/3/3
ceving
  • 3,579
  • 5
  • 24
  • 30