假设我只是创建目录 newDirectory,然后执行 ls -ld 命令。我看到硬链接的数量是2。到底是什么让硬链接从一开始就是2?另外,当前目录中的子目录数量是否等于硬链接数量 - 2?
答案1
历史上,第一个 Unix 文件系统在每个目录中创建了两个条目:.
指向目录本身,并..
指向其父目录。这为应用程序和操作系统本身提供了一种遍历文件系统的简单方法。
因此,每个目录的链接数为 2+n,其中 n 是子目录的数量。链接是该目录在其父目录中的条目、目录自己的.
条目以及..
每个子目录中的条目。例如,假设这是以 为根的子树的内容/parent
,所有目录:
/parent
/parent/dir
/parent/dir/sub1
/parent/dir/sub2
/parent/dir/sub3
那么dir
链接计数为 5:dir
中的条目/parent
、.
中的条目以及、和中各/parent/dir
三个条目。由于没有子目录,因此其链接计数为 2(中的条目和中的条目)。..
/parent/dir/sub1
/parent/dir/sub2
/parent/dir/sub3
/parent/dir/sub1
sub1
/parent/dir
.
/parent/dir/sub1
为了最大限度地减少根目录的特殊大小写,根目录没有“适当的”父目录,根目录包含一个..
指向其自身的条目。这样,它的链接计数也为 2 加上子目录的数量,2 是/.
和/..
。
后来的文件系统倾向于跟踪内存中的父目录,并且通常不需要.
并且..
作为实际条目存在;典型的现代 UNIX 系统将.
和..
视为特殊值,作为与文件系统类型无关的文件系统代码的一部分。一些文件系统仍然包含.
和..
条目,或者假装包含和条目,即使磁盘上没有出现任何内容。
请注意,即使文件系统本身包含一个..
条目,内核仍然必须处理一种特殊情况。在已挂载的文件系统的根目录中,名为 的条目..
指向目录本身:如果根目录是 inode 2,则根目录中的.
和..
条目都指向 inode 2。但是..
从该目录访问实际上必须访问挂载点的父目录,除非挂载点是/
.也就是说,假设/media/foo
是一个挂载点,/media/foo/..
则必须指定/media
,而不是/media/foo
,即使..
挂载的文件系统根目录中的条目/media/foo
指向 inode 2。
大多数文件系统仍然报告目录的链接计数为 2+n,无论.
和..
条目是否存在,但也有例外,例如 btrfs 不会执行此操作并更改此设置已被标记为被拒绝的想法在里面维基百科。
答案2
一个用于目录本身,一个用于.
目录内部。
另外,当前目录中的子目录数量是否等于硬链接数量 - 2?
这是有道理的,因为每个子目录都会创建一个..
硬链接,除此之外,您无法创建目录的硬链接。1 然而,我不会相信这是任何严重的事情,尤其是。因为很容易计算子目录并获得实际数量。
如果您只是查看ls
输出以了解有多少个潜艇,那么它确实会给您一个不错的想法。
1或者至少,你不能使用ln
.我没有尝试以编程方式进行操作,并且man 2 link
是不明确的 - 链接到目录没有明显的错误,尽管有一些可能适用(EMLINK
,EPERM
)。因此,除非有一些标准表明目录唯一可能的硬链接是.
,并且..
,我只会将硬链接计数视为临时线索。
答案3
这取决于文件系统。 BTRFS 打破了这一惯例。
# 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
链接计数器对于 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