1. Overview
1.1. 文件系统
a) 文件
包括数据(即数据项)和属性(即文件元数据,如文件长度、创建/读/写/属性时间戳、引用计数、拥有者、文件类型、访问控制列表)
目录:一种特殊的文件,提供文本名字到内部多个文件标识符的映射,可包含内部其它目录的标识符,使其层次化
b) 操作
如在UNIX上,包括如open(name, mode)
,creat(name, mode)
,close(fd)
, write(fd, buf, len)
, read(fd, buf, len)
, lseek(fd, offset, whence)
,link(name1, name2)
, unlink(name)
(删除文件的name
,即硬链接,inode.i_nlink == 0
时文件被删除)stat(name, buf)
等
1.2. 分布式文件系统
a) 需求
包含:
- 透明性:隐藏分布性,并提供良好性能和伸缩性。包括访问、位置、移动、性能、伸缩的透明性
- 并发文件更新:对并发访问进行控制
- 文件复制:文件内容在系统的不同位置要有多个拷贝,利于负载均衡和容错
- 硬件和OS异构性:文件服务接口有明确的定义,能在不同OS和计算机上实现
- 容错:在客户和服务器出现故障时服务依旧可用
- 一致性:不同地点(如客户和服务器间)的拷贝当文件被修改时,更改被同步,内容是一致的
- 安全性:请求要加以认证,消息传递要进行加密等
- 效率:至少提供传统FS相同的能力,还得满足一定的性能要求
b) 实例
主要是NFS与AFS,考虑和UNIX的VFS集成
(这2个都是类似的单个拷贝的语义,系统对可写文件仅维持一个副本)
2. 服务体系结构
分为3个组件:平面文件服务、目录服务、客户端
2.1. 平面文件服务
a) 职责
其注重实现在文件内容上的操作。(文件以UFID(唯一文件标识符)标识,在系统中唯一,即下面的file_id
)
b) 接口
客户端可使用平面文件服务的以下接口:
read(file_id, offset, len) return data
write(file_id, offset, data)
create() return file_id
delete(file_id)
get_attributes(file_id) return attr
set_attributes(file_id, attr)
与UNIX操作的不同:
- 无
open
与close
,通过合适的UFID可立即访问文件- 除了
create()
外,操作都是幂等的(而UNIX操作都不是幂等的)- 接口适合用无状态服务器实现,当服务器故障后重启,可在不需要恢复任何状态的情况下继续操作
c) 访问控制
必须在服务端继续验证。可能出现2大类问题:
- 用户标识在服务端被伪造和欺骗(未解决)
- 访问权限检查结果若存在服务器,服务器则不再是无状态的
- 将文件名转成UFID时,系统执行一次访问检查,结果以权能形式编码,作为以后一系列请求的访问许可,返回给客户
- 客户每次请求,提交用户标识,每操作一次文件时继续访问检查
2.2. 目录服务
a) 职责
提供文件的文本名字到UFID的映射,提供生成目录、为目录增加新文件名以及从目录中获得UFID的功能。
b) 接口
lookup(dir, name) return file_id
: 从目录dir
中查找文件名为name
的文件,返回file_id
add_name(dir, name)
remove_name(dir, name)
: 目录维护一个引用计数,删除条目时计数减一,若为0时,目录删除get_names(dir, re_pattern) return list<name>
c) 层次文件系统
类似UNIX,类似树形(不考虑链接),文件在叶节点上,目录在非叶结点上(类似,目录也有一个UFID)。
这时lookup(dir, name)
则是一个类似树访问的操作。
d) 文件组
文件组是在一个位于给定服务器上的文件集合,文件隶属某个文件组。
在支持文件组的系统中,UFID要包含一个文件组标识符,而文件组标识符必须在系统中全局唯一。
2.3. 客户端
运行在客户计算机上,在一个应用程序下集成和扩展了平面文件服务和目录文件服务的操作。
该程序接口可供客户计算机上的用户级程序使用。
可缓存最近使用的文件块以提高性能。