MacFUSE: New Frontiers in File Systems
Subject:   st_nlink is the number of hard links.
Date:   2007-03-16 01:35:52
From:   osxbook
Response to: st_nlink is the number of hard links.


"Oh, but they do,"

First off, when I say "directories don't have hard links", I mean you can't create a hard link to a directory (through link(2)). You are interpreting "hard link" to be synonymous with the link count of a file or directory.

"As for Mac OS X altering this aspect, perhaps it does but I doubt it. Here's a test to do on the native, non-FUSE, shipped by Apple, filesystem."

The native file system on OS X is HFS+ and not UFS. Looks like your example uses UFS, and you also seem to assume that an inode-based "traditional" Unix file system is the only way to do things.

On UFS, which indeed uses "real" inodes, you see the behavior you mentioned. That's because UFS will cause st_nlink to be set to the inode's link count. A brand new directory's inode's link count is 2. The mkdir vnode operation for UFS increments the parent directory's inode's link count. This is why you see what you're seeing.

Now, HFS+ uses a bunch of B-Trees: one for the file system's hierarchical structure (the Catalog), another for attributes, another for extents, and so on. It doesn't use inodes the way you're thinking. In fact, what's reported as the inode number isn't really an inode number, but the node number in the Catalog B-Tree. There are no inodes in HFS+. In particular, the "." and ".." entries are "fake" special cases.

Try your example on HFS+:

$ cd /tmp/foo
$ ls -ld .
drwxr-xr-x 2 user wheel 68 Mar 16 00:55 .
$ touch a b c d e f g h
$ ls -ld .
drwxr-xr-x 10 user wheel 340 Mar 16 00:56 .
$ mkdir 1 2 3
$ ls -ld .
drwxr-xr-x 13 user wheel 442 Mar 16 00:56 .

As you see, the second word of ls(1)'s output has a different meaning here. It is the number of file system objects within the directory.

How file hard links are implemented on HFS+ is interesting too, but that's another story.

Moreover, if a Mac OS X file system tells the kernel that it doesn't support the nlink field, the kernel will substitute a value of 1.

"for example to implement .., and if you are writing a filesystem you still set up those hard links when making a directory; I doubt FUSE alters this."

MacFUSE is a file system enabler--not a file system itself (well, technically, it is a file system, just a generic one). Specific file systems are free to report whatever they like for st_nlink.

It's actually a bit more complicated on Mac OS X, since there is also the concept of file system attributes. In the man page of getattrlist(2), look for ATTR_DIR_LINKCOUNT and ATTR_FILE_LINKCOUNT.

Hopes this clarifies things.

1 to 1 of 1
  1. st_nlink is the number of hard links.
    2007-03-19 11:21:06 [View]

    • st_nlink is the number of hard links.
      2007-03-21 14:57:17  osxbook [View]

1 to 1 of 1