Posix requires that the operating system understand the concept of hard links but not that hard links can actually be used in any particular circumstance. You can find out how many hard links are permitted at a particular location (this can vary by filesystem type) by calling pathconf(filename, _PC_LINK_MAX)
. The minimum limit (_POSIX_LINK_MAX
) is 8, but this is rather meaningless as link()
can report many other errors anyway (permission denied, disk full, …).
The stat
structure stores the link count in a field of type nlink_t
, so the type of this field gives an upper limit on your system. But there's a good chance you'll never be able to reach that far: it's common to have a 32-bit nlink_t
but only 16 bits in many filesystems (a quick grep in the Linux source shows that ext[234], NTFS, UFS and XFS use 16-bit link counts in the kernel data structures).
The internal structure of directories is dependent on the filesystem in use. If you want to know precisely what happens, have a look at filesystem implementations.
Basically, in most filesystems, a directory is an associative array between filenames (keys) and inodes numbers (values). Something like this¹:
1167010 .
1158721 ..
1167626 subdir
132651 barfile
132650 bazfile
This list is coded in some – more or less – efficient way inside a chain of (usually) 4KB blocks. Notice that the content of regular files is stored similarly. In the case of directories, there is no point in knowing which size is actually used inside these blocks. That's why the sizes of directories reported by du
are multiples of 4KB.
Inodes are there to tie blocks together, forming a single entity, namely a 'file' in the general sense. They are identified by a number which is some kind of address and each one is usually stored as a single, special block.
Management of all this happens in kernel mode. Software just asks for the creation of a directory with a function named int mkdir(const char *pathname, mode_t mode);
leading to a system call, and all the rest is performed behind the scenes.
About links structure:
A hard link is not a file, it's just a new directory entry (i.e. a name – inode number association) referring to a preexisting inode entity². This means that the same inode can be accessed from different pathnames. In particular, since metadatas (permissions, ownership, timestamps…) are stored within the inode, these are unique and independent of the pathname chosen to access the file.
A symbolic link is a file and it's distinct from its target. This means that it has its own inode. It used to be handled just like a regular file: the target path was stored in a data block. But now, for efficiency reasons in recent ext filesystems, paths shorter than 60 bytes long are stored within the inode itself (using the fields which would normally be used to store the pointers to data blocks).
—
1. this was obtained using ls -ai1 testdir
.
2. whose type must be different than 'directory' nowadays.
Best Answer
First a note: the
ln
command does not have options like-d
,-F
,--directory
, this is a non-portable GNUism.The feature you are looking for, is implemented by the
link(1)
command.Back to your original question:
On a typical UNIX system the decision, whether hard links on directories are possible, is made in the filesystem driver.
The Solaris UFS driver supports hard links on directories, the ZFS driver does not.
The reason why UFS on Solaris supports hard links is that AT&T was interested in this feature - UFS from BSD does not support hard linked directories.
The reason why ZFS does not support hardlinked directories is that Jeff Bonwick does not like that feature.
Regarding Linux, I would guess that Linux blocks attempts to created hard links on directories in the upper kernel layers. The reason for this assumption is that Linus Torvalds wrote code for GIT that did shred directories when
git clone
was called as root on a platform that supports hard linked directories.Note that a filesystem that supports to create hard linked directories also needs to support
unlink(1)
to remove non-empty directories as root.So if we assume that Torvalds knows how Linux works and if Linux did support hard linked directories, Torvalds should have known that calling
unlink(2)
on a directory while being root, will not return with an error but shred that directory. IN other words, it is unlikely that Linux permits a file system driver to implement hard linked directories.