4.3.4 共享文件

当几个用户同在一个项目里工作时,他们常常需要共享文件。其结果是,如果一个共享文件同时出现在属于不同用户的不同目录下,工作起来就很方便。图4-16再次给出图4-7所示的文件系统,只是C的一个文件现在也出现在B的目录下。B的目录与该共享文件的联系称为一个连接(link)。这样,文件系统本身是一个有向无环图(Directed Acyclic Graph,DAG)而不是一棵树。

阅读 ‧ 电子书库
图 4-16 有共享文件的文件系统

共享文件是方便的,但也带来一些问题。如果目录中包含磁盘地址,则当连接文件时,必须把C目录中的磁盘地址复制到B目录中。如果B或C随后又往该文件中添加内容,则新的数据块将只列入进行添加工作的用户的目录中。其他的用户对此改变是不知道的。所以违背了共享的目的。

有两种方法可以解决这一问题。在第一种解决方案中,磁盘块不列入目录,而是列入一个与文件本身关联的小型数据结构中。目录将指向这个小型数据结构。这是UNIX系统中所采用的方法(小型数据结构即是i节点)。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

在第二种解决方案中,通过让系统建立一个类型为LINK的新文件,并把该文件放在B的目录下,使得B与C的一个文件存在连接。新的文件中只包含了它所连接的文件的路径名。当B读该连接文件时,操作系统查看到要读的文件是LINK类型,则找到该文件所连接的文件的名字,并且去读那个文件。与传统(硬)连接相对比起来,这一方法称为符号连接(symbolic linking)。

以上每一种方法都有其缺点。第一种方法中,当B连接到共享文件时,i节点记录文件的所有者是C。建立一个连接并不改变所有关系(见图4-17),但它将i节点的连接计数加1,所以系统知道目前有多少目录项指向这个文件。

如果以后C试图删除这个文件,系统将面临问题。如果系统删除文件并清除i节点,B则有一个目录项指向一个无效的i节点。如果该i节点以后分配给另一个文件,则B的连接指向一个错误的文件。系统通过i节点中的计数可知该文件仍然被引用,但是没有办法找到指向该文件的全部目录项以删除它们。指向目录的指针不能存储在i节点中,原因是有可能有无数个目录。

惟一能做的就是只删除C的目录项,但是将i节点保留下来,并将计数置为1,如图4-17c所示。而现在的状况是,只有B有指向该文件的目录项,而该文件的所有者是C。如果系统进行记账或有配额,那么C将继续为该文件付账直到B决定删除它,如果真是这样,只有到计数变为0的时刻,才会删除该文件。

阅读 ‧ 电子书库
图 4-17 a)连接之前的状况;b)创建连接之后;c)当所有者删除文件后

对于符号连接,以上问题不会发生,因为只有真正的文件所有者才有一个指向i节点的指针。连接到该文件上的用户只有路径名,没有指向i节点的指针。当文件所有者删除文件时,该文件被销毁。以后若试图通过符号连接访问该文件将导致失败,因为系统不能找到该文件。删除符号连接根本不影响该文件。

符号连接的问题是需要额外的开销。必须读取包含路径的文件,然后要一个部分一个部分地扫描路径,直到找到i节点。这些操作也许需要很多次额外的磁盘存取。此外,每个符号连接都需要额外的i节点,以及额外的一个磁盘块用于存储路径,虽然如果路径名很短,作为一种优化,系统可以将它存储在i节点中。符号连接有一个优势,即只要简单地提供一个机器的网络地址以及文件在该机器上驻留的路径,就可以连接全球任何地方的机器上的文件。

还有另一个由连接带来的问题,在符号连接和其他方式中都存在。如果允许连接,文件有两个或多个路径。查找一指定目录及其子目录下的全部文件的程序将多次定位到被连接的文件。例如,一个将某一目录及其子目录下的文件转储到磁带上的程序有可能多次复制一个被连接的文件。进而,如果接着把磁带读进另一台机器,除非转储程序具有智能,否则被连接的文件将被两次复制到磁盘上,而不是只是被连接起来。