操作系统复习笔记(IV):文件管理
文件的基本概念
- 概念:以磁盘为载体的存储在计算机上的信息集合。
- 文件的组织:
- 无结构文件:一系列二进制或者字符流
- 有结构文件:逻辑上可分为顺序文件、索引文件、顺序索引文件
- 文件的组成:
- 文件名
- 数据(存储空间)
- 类型
- 索引信息
- 权限
- 创建时间和修改时间
- 所有者
- 文件的操作:
- 创建:create系统调用
- 删除:delete系统调用
- 打开:open系统调用
- 关闭:close系统调用
- 读:read系统调用
- 写:write系统调用
文件目录
文件控制块PCB
-
FCB:用于存放控制文件所需要的各种信息的数据结构,实现“以名存取”。
-
目录:FCB的有序集合。一个FCB就是一个目录项。
-
FCB的内容:
- 基本信息:文件名、物理位置、逻辑结构、物理结构
- 存取控制信息:用户的存取权限
- 使用信息:修改时间、建立时间
目录结构
单级目录结构
描述:
- 只有一张目录表,每个文件占用一张目录项。
特点:
- 不允许文件重名。
- 不适用于多用户操作系统。
示意图:
两级目录结构
文件目录分成:
- 主文件目录MFD(Master File Directory)
- 记录用户名以及相应的文件目录位置。
- 用户文件目录UFD
特点:
- 不同用户的文件名允许重名。
- 缺乏灵活性,无法实现文件分类。
示意图:
树形目录结构
示意图:
描述:
- 根目录出发的路径叫做绝对路径,引入当前路径防止每次都从根路径开始查找。
特点:
- 方便分类,层次架构清晰
- 能有效的对文件管理和保护
缺点:
- 不利于实现文件共享
无环图目录结构
示意图:
特点:
- 构成有向无环图
- 可以用不同文件名指向同一个文件/目录。
- 引入共享计数器的概念,只有当共享计时器为0时,才能真正删除结点。
索引结点
- 目的:给目录瘦身
- 检索文件时,文件的其它描述信息无需调入内存。
- UNIX中,文件名和文件描述信息是分开的。
- 索引节点inode:存放文件描述信息的数据结构。
- 文件目录的目录项 = 文件名 + 指向该文件的INode指针
定量的角度看引入inode的好处
磁盘inode
- 每个文件都有一个唯一的磁盘inode,存放于磁盘。
- 组成:
- 用户标识符:个人/group
- 存取权限:各类用户的权限
- 文件类型:普通/目录/可执行
- 物理地址:每个inode有13个地址项,直接或间接给数据文件所在盘块编号。
- 长度
- 链接计数:文件系统中所有指向该文件的文件名的计数
- 存取时间
内存inode
- 文件被打开时,将磁盘inode复制到内存的inode中。
- 新增内容:
- 内存inode编号
- 状态:上锁/修改
- 访问计数:进程访问则+1
- 逻辑设备号:所属的文件系统的设备号
- 链接指针:指向空闲链表/散列队列的指针
文件的逻辑结构
逻辑结构的分类:
- 无结构文件:流式文件,不是重点。
- 有结构文件:记录式文件。
- 每条记录 = 若干数据项(其中一个数据项可以作为关键词)分为:定长记录/可变长记录
- 分类:
- 顺序文件
- 索引文件
- 索引顺序文件
顺序文件
- 概念:记录在逻辑是一个接着一个的。
- 记录可以是定长或者可变长。
- 物理上可以是顺序(类似顺序表)也可以是链式(类似链表)
- 简单记录间的顺序分类:
- 串结构:记录之间的顺序和关键字无关
- 顺序结构:记录之间按照关键字进行顺序排列
- 按照物理结构分类:
- 链式存储:无法实现随机存取。
- 顺序存储:
- 可变长记录:(维护记录长度和记录内容)没有规律性,无法实现随机存取。
- 定长记录:可以实现随机存取
- 如果采用串结构:无法快速找到关键字的记录。
- 如果采用顺序结构:可以快速找到关键字的记录,如折半查找。但是增加和删除一条记录比较困难。
索引文件
需求:对于可变长的文件,无法通过随机访问进行查找,效率比较低。
索引表:
- 表项物理上连续存放,表项本身是定长记录的顺序文件。
- 表项包含:指向变长记录的指针,文件长度。
好处:把对变长记录顺序文件的检索转变对对定长记录索引文件的随机检索。大大提速。
索引顺序文件
索引文件的缺点:空间利用率问题。
- 每条记录对应一个索引表项,可能会很大。
索引顺序文件:一组记录对应一个索引表项。查找一条记录时,首先通过索引表找到所在组,然后再组内使用顺序查找。
示意图:
多级索引顺序文件:为顺序文件建立多级索引表。
文件的物理结构(重点)
对磁盘块管理可以划分为两种:
- 非空闲块(存放了文件数据的磁盘块)管理——文件的物理结构探讨
- 空闲块管理——文件存储空间管理探讨
文件物理结构大致可分为三种:
- 连续分配
- 链式分配
- 隐式分配
- 显式分配
- 索引分配
磁盘块
- 磁盘中的存储单元会被分为一个个块。一般来说,磁盘块大小和内存页的页面大小相同。内存和磁盘的交互都是以块为单位。
- 由此,文件的逻辑地址可以表示为(逻辑块号,块内地址)的形式。
- 操作系统负责从逻辑块号映射到物理块号
连续分配
- 描述:逻辑的文件相邻物理上也必须要相邻。
- 特点:
- 目录项中包含 “起始块号start”和 “文件长度length”
- 物理块号 = 起始块号+逻辑块号
- 好处:
- 磁盘寻道数和寻道时间最小
- 支持随机访问
- 缺点
- 文件长度不好动态增加,可能需要大量移动
- 删除和插入需要移动磁盘块
- 反复增删会产生外部碎片,存储空间利用率低
链接分配
隐式链接
介绍:
- FCB包含:起始块号、结束块号。
- 每个磁盘块中都会保存指向下一个盘块的指针。
- 读入i号逻辑块,一定需要i+1次IO。
优点:
- 方便扩展,不会有碎片问题,内存利用率高
缺点:
- 不支持随机访问,仅仅支持顺序访问。
- 存储下一个盘块需要耗费一些空间。
显式链接
描述:
- 目录项:仅需要存储起始块号。
- FAT:把用于链接文件各个物理块的指针显式地放在一张文件分配表(FAT) 中。
- 一个磁盘仅设置一张FAT表,开机时将FAT读入内存,常驻内存。
好处:
- 支持随机访问。
- 逻辑块号到物理块号的转换过程是不需要经过IO操作的。而且不需要访问0-i-1个逻辑块。
- 方便文件扩展,不会有碎片问题。
缺点:
- FAT会占用一定的存储空间。
索引分配
描述:
- 索引表:每个文件建立一张索引表,记录逻辑块对应的物理块。
- 索引块:索引表存放的磁盘块。
- 数据块:文件数据存放的磁盘块。
- PCB中记录:文件的索引块是几号。
注意区别:显式链接分配中,FAT是整个磁盘只有一张。索引表是每个文件一张。
优点:
- 支持随机访问,文件扩展(分配一个空闲块+索引表项)也容易。
如何解决一个磁盘块无法装入整个索引表?
- 链接方案:多个索引块链接起来存放。
- 多层索引:类似多级页表的原理,第一层索引块指向第二层的索引块。
- 混合索引:多种索引分配方式的结合。顶级索引表既包含直接地址索引,还有一级间接索引和二级间接索引。
- 访问直接地址索引:两次IO。
- 访问一级索引:三次IO。
- 访问二级索引:四次IO。
计算题考点
- 根据多级索引、混合索引的结构计算文件的最大长度。核心是索引表最大不能超过一个块。
- 分析访问某个数据块需要的读磁盘次数。需要注意题目是否给了顶级索引块已经调入内存。
逻辑结构VS物理结构
- 索引文件的索引表:用户自己建立的。存放关键字到逻辑地址。
- 索引分配的索引表:OS建立的。存放逻辑块号到物理块号的映射。
文件存储空间管理
三个核心问题:
- 空闲块的记录和组织
- 空闲块的分配
- 回收磁盘块
磁盘分区:
- 目录区:文件目录信息、磁盘存储空间管理信息
- 文件区:存放文件数据。
空闲表法
- 适合:连续分配方式。
- 具体算法:首次适应、最佳适应、最坏适应
- 回收:分为四种情况,前后都没空闲、前后都是空闲、前面是空闲、后面是空闲。
空闲链表法
空闲链表法可以分为:
- 空闲盘块链:以盘块位单位组成一条空闲链。
- 空闲盘区链:以盘区为单位组成一条空闲链。
空闲链表法:
- 操作系统保存着链头和链尾指针
- 分配:可以根据算法从链头开始检索,找到一个符合的就分配。
- 回收:如果有相邻的空闲分区就加到相邻,如果没有就作为单独的空闲盘区。
位视图法
- 0表示空闲,1表示已分配。
- 一般用连续的字来表示,上面图片的字长是16位。可以用(字号,位号)来表示一个地址。
- 分配:假设文件需要K个块,从头扫描找到K个相邻或者不相邻的0;然后根据字号和位号算出对应的盘块号,分配个给文件;将位设置为1.
- 回收:根据盘块号计算出字号和位号,设置为0
做题需要注意字号和位号是从0开始还是从1开始。
成组链接法:有点复杂,据说很少考
-
空闲表法和空闲链表法的缺点:不适用于大型文件系统,因为空闲表和空闲链表可能过大。
-
UNIX中采用成组链接法对磁盘块进行管理。
-
超级块:文件卷的目录区的一个专门的磁盘块。启动时读入内存。保证数据一致性。
-
超级块中的第一个块是下一组空闲盘块数,其余是空闲块号。
-
分配:
- 假设需要1个空闲块,检测第一个分组的块数是否组成,足够就分配第一个分组中的1个空闲块,修改对应数据。
- 假设分配100个空闲块,
文件基本操作
删除:
- 根据路径找到目录文件,从目录中找到FCB
- 根据FCB中外存位置,回收磁盘块——根据不同策略。
- 从目录表中删除文件对应的FCB。
打开:
- 根据路径找到目录文件,从目录中找到FCB
- 检测用户是否有权限
- 从目录项复制到内存的打开文件表,将表目编号返回给用户。用户使用打开文件表编号来指明文件。
- 整个系统有一张打开文件表,维护计数器。
- 每个进程都有一张打开文件表,维护读写指针,访问权限和系统表索引号。
关闭:
- 将进程的打开文件表的FCB删除
- 回收空间
- 系统打开文件表count--,如果count=0则删除表项。
文件共享
硬链接:基于inode
- inode设置一个计数变量count,表示链接到本索引节点上的用户目录项数。
- 用户删除文件,只是把用户目录中与该文件对应的FCB删除,且inode的count-1,
软链接:基于符号链
- 本质上是一种link类型的文件,会层层查找目录,最终找到表项。
- 文件被删了,link文件依然存在,只是无法通过link文件找到原文件。
- link方式查找共享文件需要查询多级目录,会有多次磁盘IO。
文件保护
口令保护
- 描述:为文件设置一个口令,存放在FCB或者inode中。用户访问需要先输入口令。
- 优点:保存和验证口令的开销不大
- 缺点:正确的口令放在系统内部,不安全。
加密保护
- 描述:用户设置某个密码对文件加密,访问文件需要提供正确密码才能解密。
- 举例:对文件数据进行xor🔐
- 优点:保密性好,无须存储密码。
- 缺点:加密解密需要耗费一定的时间。
访问控制
- 访问控制列表ACL:对每个FCB设置一个访问控制列表ACL。记录可以对文件进行什么操作。
- 可以以组对单位,标识各个足用户对文件之星什么操作。
文件系统的层次结构
- 用户接口:系统调用。
- 文件目录系统:根据文件路径找到FCB或者inode。
- 工作:目录和目录项相关的操作。如:管理活跃的文件目录表、管理打开文件表
- 存取控制模块:完成文件保护相关工作。
- 逻辑文件系统和文件信息缓冲区:用户指明想要访问文件记录号,将记录号转逻辑地址。
- 物理文件系统:把将逻辑地址转物理地址。
- 辅助分配模块:负责文件存储空间管理,即负责分配和回收存储空间。
- 设备管理模块:直接和硬件打交道。如分配设备、分配设备缓冲区、磁盘调度等。
文件系统的全局结构
-
物理格式化:低级格式化,划分扇区,检测坏扇区,用备份扇区替换坏扇区。坏扇区对OS来说也是透明的。
-
逻辑格式化:磁盘分区,完成各个分区的文件系统初始化。
- 示意图:
- 示意图:
-
灰色部分有实际数据,白色部分无实际数据。
- 引导块:负责开机初始化
- 超级块
- 位示图
- inode区
- 根目录
文件系统在内存中的结构
- 用户区:文件描述符。
- 内核区:
- 目录的缓存:为了加快读写速度。
- 系统的打开文件表:索引 - FCB - 打开计数
- 进程的打开文件表:索引 - 打开方式 - 系统打开文件表索引
open系统调用的原理:
- open根据路径读入目录
- 根据目录找到FCB,复制到内存的打开文件表
- 在进程打开文件表创建一条记录,返回fd。
虚拟文件系统
在普通文件系统中,内核中对应多套文件系统。比如:
- 磁盘的UFS文件系统
- 移动硬盘的NTFS文件系统
- U盘的FAT文件系统
虚拟文件系统中,进程只需要好虚拟文件系统VFS打交道。VFS负责和各个文件系统打交道。
- VFS通过POSIX标准接口提供api,屏蔽底层的实现差异。
- VFS要求下层文件系统必须实现某些规定的函数,一个新文件系统要在OS上被使用就必须满足该操作系统的要求。
- 存在的问题:不同文件系统表示文件的数据结构不同。因此每打开一个文件,VFS就在内存中新建一个vnode,用统一的数据结构表示文件。vnode仅存在主存,而inode会被调入主存,也会在外存中存储。
- vnode中的函数指针指向各个文件系统中的功能函数。
文件系统挂载
文件系统挂载指的是文件系统的安装和装载,文件系统挂载要做下面的事情:
- 在VFS中注册新挂载的文件系统。内存中的挂载表包含每个文件系统的相关信息,包括系统类型和容量大小。
- 新挂载的文件系统要向VFS提供一个函数地址列表。
- 将新文件系统加到挂载点,也就是新文件系统挂载到某个父目录下。
- 感谢你赐予我前进的力量