文件系统基础
文件系统基础
- 为什么我们需要文件系统
- 持久化保存数据需求(Persistence)
- 进程结束、关机/关电、宕机/掉电
- 使用持久化存储设备:磁盘、SSD等
- FS 是对持久化数据存储的抽象
- 给用户/程序开发者提供一个逻辑上的持久化存储
- 文件、目录形式
- 简单、易理解、操作方便
- 将复杂的、公共的管理功能从用户程序中移出
- 存储设备管理,例如磁盘
- 数据管理,即程序持久化数据的组织和增删改查
- 给用户/程序开发者提供一个逻辑上的持久化存储
- 对FS的基本需求
- 能够保存大量(复杂多样)的信息 -> 管理问题
- 多个进程同时访问 -> 并发控制问题
- 多用户共享数据 & 私有数据 -> 安全保护问题
文件系统的用户视图
- 文件:数据组织的单位
- 文件是命名的字节数组
- 用户将数据组织成文件,根据文件名来访问对应的数据
- FS不感知文件的内容:使用文件的进程负责解析内容
- 目录:文件组织的单位
- 一组文件和目录的命名集合
- 父目录、子目录
- 同一目录下没有重名的
- 名字空间:树形层次结构
- 文件系统的逻辑视图
文件
- 文件名:由字母、数字及某些特殊字符组成的字符串
- 用户根据文件名来访问文件
- 文件扩展名:描述文件的用途
- 文件属性
- 文件大小、所有者、时间戳、访问权限
- 文件逻辑地址:0..fsize-1,指示数据在文件中的位置
- 文件内容:无结构
- OS将文件视为无结构的字节数组
- 程序开发者可以定义任意结构的文件
- 文件的类型
- 常规文件、目录文件、设备文件、可执行文件
- 文件的访问
- 打开文件 & 文件描述符
- 当前位置:文件内部的逻辑地址,范围是[0,fsize-1]
- 访问方式(Access Mode):读,写,执行
- 文件的访问模式(Access Pattern)
- 顺序访问
- 从头到尾依次访问每个文件块
- 顺序访问文件 不等于 磁盘上顺序访问扇区
- 随机访问
- 每次随机访问一个文件块
- 按关键字访问
- 查找包含关键字的文件及段落
- 文件系统本身不提供此功能,需要借助应用程序完成
- 与之相比,数据库自身可以实现按关键字查找记录
- 顺序访问
目录
- 路径
- 根目录 & 当前工作目录
- . : 当前目录
- .. : 根目录
- 绝对路径 vs 相对路径
- 目录:一种特殊的文件
- 命中 & 属性
- 目录和文件用相同的数据结构(inode)
- 通过一个标志(i_mode)来区分文件和目录
- 目录内容:描述它所包含的目录和文件集合
- 有结构:逻辑上是一张表
- 目录项:每个成员一项
- 不同的FS采用不同的结构
- 由FS负责维护和解析目录内容
- 访问目录 vs 访问文件:通过不同的syscall实现
链接
- 硬链接
- 为文件共享提供的一种手段
- 为文件创建一个新名字,无数据拷贝
- 多个名字可以指向同一个文件
- 一个文件可以同时拥有多个名字,甚至位于多个目录中
- 限制
- 不能跨文件系统
- 不能链接目录
- 为文件共享提供的一种手段
- 符号链接
- 另一种文件共享的手段
- 创造一个普通文件,内容为目标地址的路径(绝对路径/相对路径)
- 另一种文件共享的手段
文件系统内部结构
虚拟文件系统 和 物理文件系统
- 虚拟文件系统
- 同时挂载不同类型的FS
- SUNFS访问本地的磁盘
- SUN NFS访问远端服务器的FS
- 实现FS接口和通用功能
- 同时挂载不同类型的FS
- 物理文件系统
- 磁盘布局、数据结构、磁盘空间管理、名字空间管理等
- 虚拟文件系统开关表
- 用于物理文件系统的挂载与卸载
- 每一种类型的文件系统有一个表项
- 文件系统类型的名字
- 初始化函数指针,用于 mount
- 清除函数指针,用于 umount
- 例子:
mount -t ext4 /dev/sdb /home/os- 前提:
- 文件系统类型ext4必须事先加载进内核
- 挂载目录 /home/os 必须要已经创建好
- 步骤
- 根据文件系统类型,查VFS开关表,找到该ext4类型FS的初始化函数,即
ext4_mount() - 调用
ext4_mount- 读取
superblock - 读取根目录
i-node
- 读取
- 初始化一些内存数据结构
- 根据文件系统类型,查VFS开关表,找到该ext4类型FS的初始化函数,即
- 前提:
文件系统主要数据结构
i-node
inode:描述文件/目录,也成为文件元数据
- 每个文件用一个i-node来描述
- 文件元数据
- mode: 文件类型和访问权限
- size: 文件大小
- nlinks: 硬链接数
- uid: 所有者的user id
- gid: 所有者的group id
- ctime: 文件创建的时间戳
- atime: 上一次访问文件的时间戳
- mtime: 上一次修改文件的时间戳
- ino:inode number,即i-node的ID,唯一标识一个文件(在一个FS内)
- 文件块的索引信息:文件块的磁盘位置信息
- <offset,count> -> 磁盘上的位置 (文件块# -> 磁盘逻辑块# LBN)
- 不同的FS采取不同的索引机制
目录项(dentry)
dentry: 目录项,记录文件和inode的对应关系
- 目录内容为它所包含的所有子目录和文件的名字及其ino
- 不包含子目录的内容
- 逻辑上,目录是一张映射表
- 目录项(dentry): 文件名 -> ino
- 物理上,目录项是一个字节数组
- 文件名不等长,数组每一项不等长
- 路径解析
- 根据路径名,获得其ino
- 逐级目录查找
- 例子:
/home/os/fs01.ppt- 从根目录开始,查找
/home的ino - 在
home目录下查找os的ino - 再
os目录下查找fs01.ppt的ino - 根据
fs01.ppt的ino,找到其数据块,进行读写操作
- 从根目录开始,查找
打开文件表(Open-file table)
打开文件表:记录进程打开的文件信息
- 打开文件,通过
fd = open(path,flags,mode)实现 - 打开文件表: Open-file table
- 通过打开文件表(在内存中)把进程与文件的i-node进行关联
- 路径名解析和权限检查,得到path的ino,读出它的inode(保存在磁盘上)
- 将磁盘i-node拷贝到一个内存i-node结构中,在打开文件表中增加一项,包含以下内容
- 文件的Reference Count
- 当前文件的偏移量
- 文件的访问模式
- 内存inode结构的指针
文件描述符表:File Descriptor Table
- 每个进程有一个文件描述符表
- 指针数组,每个指针指向打开文件表中的一项,表示一个打开文件
- 该指针在文件描述符表中的下表,即文件描述符fd
超级块(superblock)
superblock: 描述文件系统基本信息
- 定义一个文件系统
- 数据块的大小
- i-node的大小
- 数据块总数
- i-node总数
- 根目录ino
- i-node表的起始地址
- Block Bitmap的起始地址
- i-node Bitmap的起始地址
- 当前状态
- 数据块的使用状态:已使用的块数、预留的块数、剩余的块数...
- i-node的使用状态:已使用的i-node数、预留的i-node数、剩余的i-node数...
文件系统的磁盘布局
Boot Block | Superblock | Block Bitmap | i-node Bitmap | I-node Array | Data Blocks
- 引导块
- 启动OS的代码
- Superblock:定义一个FS
- FS的相关信息
- 空闲空间管理相关的信息
- Block Bitmap
- i-node Bitmap
- i-node表
- 每个i-node描述一个文件或目录
- 数据块
- 文件块或目录块