文件系统

文件系统是操作系统中管理持久性数据的子系统,提供数据存储和访问功能,可以提供组织、检索、读写访问数据功能。在没有文件系统时,我们在计算机上操作的数据无法有效保存,在计算机关机再重启时数据就丢失了。大多数计算机系统都有文件系统,我们常用的谷歌也是一个文件系统,支持分布式应用的数据管理,可以支持系统监控、故障检测、故障容忍和自动恢复,提供很高的可靠性。

文件系统的概念

文件系统的主要目的是实现对文件的按名存取(从用户的角度来看),而文件管理实际上是对辅助存储空间的管理。

文件是具有符号名,由字节序列构成的数据项集合。

  • 文件是文件系统的基本数据单位
  • 文件名是文件的标识符号

文件系统的功能

分配文件磁盘空间

  • 管理文件块(位置和顺序)
  • 管理空闲空间(位置)
  • 分配算法(策略)

管理文件集合

  • 定位 文件及其内容
  • 命名 通过名字找到文件
  • 文件系统结构 文件组织方式

确保数据可靠和安全

  • 安全 多层次保护数据安全
  • 可靠 持久保存文件,避免系统崩溃、攻击

文件属性

名称、类型、位置、大小、保护、创建者、创建时间、最近修改时间等

文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。

文件头 文件系统元数据中的文件信息

  • 文件属性
  • 文件存储位置和顺序

文件描述符

进程访问文件数据前必须先打开文件,内核跟踪所有打开的文件。

操作系统在打开文件表中维护的打开文件状态和信息。文件描述符是打开文件的标识,由于打开文件表中文件数目和文件系统中文件有数量级差别,所以另外维护文件描述符而不是直接引用文件标识。

文件指针

  • 最近一次读写位置
  • 每个进程分别维护自己的打开文件指针

文件打开计数

  • 当前打开文件的次数
  • 最后一个进程关闭文件时,将其从打开文件表中移除

文件的磁盘位置

  • 缓存数据访问信息

  • 访问权限

    • 每个进程的文件访问模式信息(以什么方式访问)

文件的用户视图和系统视图

  • 文件的用户视图
    • 持久的数据结构
  • 系统访问接口
    • 字节序列的集合(Unix)
    • 系统不关心存储在磁盘上的数据结构
  • 操作系统的文件视图
    • 数据块的集合
    • 数据块是逻辑存储单元,而扇区是物理存储单元
    • 块大小和扇区大小通常是不同的,通常是几个扇区构成一个数据块

用户视图到系统视图的转换

文件系统中最小基本单位为数据块,磁盘最小访问单位为扇区。

  • 进程读文件
    • 获取字节所在的数据块(数据块是逻辑存储单位)
    • 返回数据块内对应部分
  • 进程写文件
    • 获取数据块
    • 修改数据块中对应部分
    • 写回数据块

访问模式

进程如何访问文件

顺序访问

  • 按字节依次读取
  • 大多数文件访问都是顺序访问

随机访问

  • 从中间读写
  • 不常用,但很重要
  • 虚拟内存中把内存页存储在文件

索引访问

  • 依据数据特征索引
  • 通常操作系统不完整提供索引访问
  • 数据库是建立在索引内容的磁盘访问之上

文件内部结构

  • 无结构
    • 单词、字节序列
  • 简单记录结构
    • 分列
    • 固定长度
    • 可变长度
  • 复杂结构
    • 格式化的文档(PDF Word),应用程序可根据文档格式对文件进行识别
    • 可执行文件

文件共享和访问控制

多用户系统中的文件共享是很有必要的

  • 访问控制
    • 每个用户能够获得哪些文件的哪些访问权限
    • 访问模式:读、写、执行、删除、列表
  • 文件访问控制列表(ACL)
    • <文件实体, 权限>
  • Unix模式
    • <用户|组|所有人, 读|写|可执行>
    • 用户标识ID 识别用户,表明每个用户所允许的权限及保护模式
    • 组标识ID 允许用户组成组,并指定了组访问权限

语义一致性

规定多进程如何同时访问共享文件

  • 与同步算法相似
  • 因磁盘I/O和网络延迟而设计简单

Unix文件系统(UFS)语义

  • 对打开文件的写入内容立即对其他打开同一文件的其他用户可见
  • 共享文件指针允许多用户同时读取和写入文件

会话语义

  • 写入内容只有当文件关闭时可见( 效率低)

读写锁

  • 一些操作系统和文件系统提供该功能

目录

分层文件系统

目录操作

操作系统应该只允许内核修改目录,以确保映射的完整性。应用程序通过系统调用访问目录。

  • 搜索文件
  • 创建文件
  • 删除文件
  • 列目录
  • 重命名文件
  • 遍历路径

目录实现

文件名的线性列表 包含了指向数据块的指针

  • 编程简单
  • 执行搜索耗时

哈希表

  • 减少目录搜索时间
  • 冲突 两个文件名的哈希值相同
  • 固定大小

文件别名

硬链接中文件的删除操作在删除最后一个文件项时才删除。

名字解析(路径遍历)

名字解析是指将逻辑名字转换成物理资源(文件)

有以下两种名字解析的方式

  • 遍历文件目录直到找到目标文件
  • 根据路径名在文件系统中找到实际文件位置

比如:当解析 "/bin/ls"

  • 读取根目录的文件头(在磁盘固定位置)
  • 读取根目录的数据块,搜索 bin 项
  • 读取 bin 的文件头
  • 读取 bin的数据块,搜索 ls项
  • 读取 ls 的文件头

当前工作目录(PWD)

  • 每个进程都会指向一个文件目录用于解析文件名(可以提高效率)
  • 允许用户指定相对路径来代替绝对路径 如 PWD="/bin” 能够解析 “ls”

文件系统挂载

文件系统种类

  • 磁盘文件系统
    • 文件存储在数据存储设备上 如磁盘
    • FAT,NTFS,ext2/3, ISO9660
  • 数据库文件系统
    • 文件特征是可被寻址辨识的
    • WinFS
  • 日志文件系统
    • 记录文件系统的修改/事件
    • 以原子形式记录访问
  • 网络/分布式文件系统(通过网络访问)
    • NFS、SMB、AFS、GFS
  • 特殊/虚拟文件系统
    • 管道

网络/分布式文件系统

文件可以通过网络被共享

  • 文件处于远程服务器
  • 客户端远程挂载服务器文件系统
  • 标准系统文件访问被转换成远程访问
  • 标准文件共享协议
    • NFS for Unix
    • CIFS for Windows

分布式文件系统的挑战

  • 客户端和客户端上的用户辨别起来很复杂
  • NFS 不安全
  • 一致性问题
  • 错误处理

虚拟文件系统

文件系统的实现

目的

  • 对所有不同文件系统的抽象,多种文件系统,对上提供一致的访问接口

功能

  • 提供相同的文件和文件系统接口
  • 管理所有文件和文件系统关联的数据结构
  • 高效查询例程,遍历文件系统
  • 与特定文件系统模块的交互

文件系统基本数据结构

  • 文件卷控制块(Unix superblock)
    • 每个文件系统一个
    • 文件系统详细信息
    • 块、块大小、空余块、计数/指针
  • 文件控制块(Unix vnode or inode)
    • 每个文件一个
    • 文件详细信息
    • 访问权限、拥有者、大小、数据块位置
  • 目录项(Linux dentry)
    • 每个目录项一个(目录和文件)
    • 将目录项数据结构及树型布局编码成树型数据结构
    • 指向文件控制块、父目录、子目录

文件系统的组织视图

文件系统的存储结构

  • 文件系统数据结构
    • 卷控制块(superblock 每个文件系统一个)
    • 文件控制块(inode 每个文件一个)
    • 目录节点(dentry 每个目录项一个)
  • 以上都持久存储在外存中
    • 存储设备的数据块中
  • 当需要时加载进内存
    • 卷控制模块 当文件系统挂载时进入内存
    • 文件控制块 当文件被访问时候进入内存
    • 目录节点 在遍历一个文件路径时进入内存

文件系统的存储视图

文件缓存

多种磁盘缓存位置

文件缓存有数据块缓存和页缓存两种方式。

数据块缓存

  • 数据块按需进入内存
    • 提供read()操作
    • 预读 预先读取后面的数据块
  • 数据块使用后被缓存
    • 假设数据将会再次用到
    • 写操作可能被缓存和延迟写入

页缓存

  • 虚拟页式存储
    • 在虚拟地址空间中虚拟页面可映射到本地外存文件中
  • 文件数据块的页缓存
    • 在虚拟内存中文件数据块被映射成页
    • 文件的读/写操作被转换成对内存的访问
    • 可能导致缺页或被设置为脏页
    • 会带来问题 页面置换算法需要协调虚拟存储和页缓存间的页面数

文件系统中打开文件的数据结构

  • 文件描述符
    • 每个被打开的文件都有一个文件描述符
    • 文件状态信息 目录项、当前文件指针、文件操作设置
  • 打开文件表
    • 每个进程都有一个打开文件表
    • 一个系统级的打开文件表
    • 有文件被打开, 文件卷就不能被卸载

打开文件锁

一些文件系统提供文件锁 用于协调多进程的文件访问

  • 强制 根据锁保持情况和访问需求确定是否拒绝访问
  • 劝告 进程可以查找锁的状态来决定怎么做

文件分配

文件大小

  • 大多数文件都很小
    • 需要对小文件提供很好的支持
    • 数据块空间不能太大
  • 一些文件非常大
    • 必须支持大文件(64位文件偏移)
    • 大文件访问需要高效

分配方式

  • 连续分配
  • 链式分配
  • 索引分配

指标

  • 存储效率 外部碎片(连续分配),忽略内碎片
  • 读写性能 访问速度

连续分配

链式分配

索引分配

大文件的索引分配

UFS多级索引分配

(UFS Unix File System)

  • 文件头包含13个指针
    • 10个指针指向数据块
    • 第1个指针指向索引块
    • 第12个指针指向二级索引块
    • 第13个指针指向三级索引块
  • 效果
    • 提高了文件大小限制阈值
    • 动态分配数据块 文件扩展很容易
    • 小文件开销小
    • 只为大文件分配间接索引块 大文件在访问数据块时需要大量查询