Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Saltzer和Kaashoek的《计算机系统设计原理》第1版第100页有错误吗?_C_Unix_Operating System - Fatal编程技术网

C Saltzer和Kaashoek的《计算机系统设计原理》第1版第100页有错误吗?

C Saltzer和Kaashoek的《计算机系统设计原理》第1版第100页有错误吗?,c,unix,operating-system,C,Unix,Operating System,这个问题是关于Jerome Saltzer和M.Frans Kaashoek的《计算机系统设计原理》(2009年第1版)一书中的一段,该书在麻省理工学院6.033计算机工程课程中使用 本章的一部分讨论了Unix版本6中的文件系统是如何实现的。在第100页,它讨论了链接(又名同义词、别名),特别是取消链接的操作 在名为inode的数据结构中,您可以跟踪对该inode的引用数量,这样每当您将名称与该inode解除链接时,引用计数将下降1,如果它达到零,您可以释放inode使用的内存块及其引用的所有内

这个问题是关于Jerome Saltzer和M.Frans Kaashoek的《计算机系统设计原理》(2009年第1版)一书中的一段,该书在麻省理工学院6.033计算机工程课程中使用

本章的一部分讨论了Unix版本6中的文件系统是如何实现的。在第100页,它讨论了链接(又名同义词、别名),特别是取消链接的操作

在名为inode的数据结构中,您可以跟踪对该inode的引用数量,这样每当您将名称与该inode解除链接时,引用计数将下降1,如果它达到零,您可以释放inode使用的内存块及其引用的所有内存块

然而,有一部分讨论了命名图中的循环,即目录层次结构(由于链接,我们有一个有向图,由于文件名中存在的结构,我们有一个层次结构,文件名是由用正斜杠分隔的层次组件组成的路径名)

要开始文本定义链接操作的伪代码,请执行以下操作:
LINK(“Mail/inbox'new-assignment”、“assignment”)
使
assignment
成为
Mail/inbox/new assignment
目录中
项目的同义词,如果后者是当前工作目录

以下是我感到困惑的文本部分:

仅当命名中没有循环时,使用引用计数才有效 图表确保unix命名网络是有向图 如果没有循环,unix文件系统将禁止指向目录的链接。到 看看为什么避免循环,考虑一个目录“A”,其中包含一个 目录“b”。如果程序调用中的链接(“a/b/c”、“a”) 包含“a”的目录,则系统将返回一个错误并 不执行该操作。如果系统已执行此操作, 它会创造一个从“c”到“a”的循环,并且会增加 “a”索引节点中的引用计数为1。如果是一个程序那么 调用unlink(“a”),名称“a”被删除,但inode和 不会删除“a”块,因为 “a”的inode仍然是正的(因为从“c”到“a”的链接)。 但一旦名称“a”被删除,用户将无法再访问 将目录命名为“a”,并且也无法删除它。在里面 在这种情况下,目录“a”及其子目录将是 已断开与命名图的连接,但系统不会将其删除 因为“a”的inode中的引用计数仍然为正。信息技术 可以检测这种情况,例如使用垃圾 收集,但这样做很昂贵。相反,设计师选择了 一个更简单的解决方案:不允许指向目录的链接,这排除了 循环的可能性

我这里的问题是:

1) 如果一个程序在包含“a”的目录中调用一个链接(“a/b/c”,“a”),并且它成功地“创建了一个从“c”到“a”的循环”?毕竟我们是在将包含“a”到“c”的目录中的名称“a”链接起来。这是文本中的错误吗?我们不是真的调用链接(“a”,“a/b/c”)来创建从“a/b/c”到“a”的链接吗

文本说我们增加了索引节点“a”的引用数量,如果我们确实从“a/b/c”链接到“a”,那么我同意

如果我们随后取消链接(“a”),我们将删除包含“a”的目录上下文中的绑定,但是名称“a”被绑定到的inode不会被删除,因为“c”仍然有对它的引用

文本表示目录“a”及其子目录将与命名图断开连接,但系统不会删除它,因为“a”的引用计数仍然为正


2) 它断开连接的原因与“b”断开连接的原因相同,对吗?如果我们断开“a”的链接,我们将删除对包含命名方案的inode的引用,其中“b”绑定到它的inode。因为我们无法访问“a”,我们无法访问“b”,因此我们无法从“c”访问“c”或“a”“再也没有了。因此,我们断开了所有这些子目录的连接。

答案需要对Unix文件系统的功能有比我所能提供的更深的理解。尽管如此,我还是试了一下

目录
a/b
中的文件
c
别名为目录
a
中的名称
a

(似乎目录中的名称必须是唯一的,并且在同一目录中不能存在文件
a
和目录
a
。)

由于名称
a
已经存在,因此文件
c
将等同于目录
a
。访问
a/b/c
现在将访问目录
a
,我们可以做
a/b/c/b/c…
,这是一个循环

一个
的链接数会增加。取消链接
a
将从inode中删除目录
a
,但由于链接计数不是零,因此不会释放
a
的存储


(到目前为止,请尝试进行解释-让我们阅读和评论。)

您是正确的,这本书中有一个错误,或者它描述的
link
操作是使用从POSIX系统调用
link
ln
实用程序中交换的参数定义的

这本书描述的是操作

link("a", "a/b/c")
使用声明为
int-link的链接(2)(const-char*oldpath,const-char*newpath)

ln a a/b/c
使用POSIX标准化实用程序,当当前工作目录是
a
的父目录时执行

除此之外,文本是正确的。众所周知,单靠引用计数无法收集循环。与其允许,不如更容易地禁止硬林