来源:操作系统_清华大学(向勇、陈渝)
参考文章:https://blog.csdn.net/github_36487770/article/details/79445896
1.总体介绍
基本概念、虚拟文件系统、数据块缓存、打开文件的数据结构、文件分配、空闲空间列表、多磁盘管理-RAID、磁盘调度
2.基本概念
基本概念:文件系统,块,文件描述符,目录,文件别名,文件系统的种类
3.文件系统和文件
文件系统:一种用于持久性存储的系统抽象。
在存储器上,文件系统用于组织、控制、导航、访问和检索数据。
文件:文件系统中一个单元的相关数据在操作系统中的抽象。
4.文件系统的功能
文件系统的功能:
- 分配文件磁盘空间:1.管理文件块(哪一块属于哪一个文件),2.空闲空间(哪一块是空闲的),3.分配算法(策略)
- 管理文件集合:1.定位文件及其内容,2.命名:通过名字找到文件的接口,3.分层文件系统,文件系统类型 ,
- 提供的便利及特征:1.分层等来保护数据安全,2.可靠性/持久性,保持文件的持久即使发送崩溃、媒体错误、攻击等。
5.文件和块
文件属性:名称、类型、位置、大小、保护、创建者、创建时间、最近修改时间、…
文件头:
1.在存储元数据中保存了每个文件的信息
2.保存文件的属性
3.跟踪哪一块存储块属于逻辑上文件结构的哪个偏移
6.文件描述符
文件描述符—用整数代表f
必须先打开文件
f = opea(name , flag)
…
…= read(f,..)
…
close(f)
内核跟踪每个进程打开的文件:
1.操作系统为每个进程维护一个打开文件表
2.一个打开文件描述符是这个表中的索引
内核跟踪每个进程打开的文件,需要元数据来管理:
1.文件指针,指向最近的一次读写位置,每个打开了这个文件的进程都指向这个指针
2.文件打开计数,记录文件打开的次数,当最后一个进程关闭了文件时,允许将其从打开文件表中移除
3.文件磁盘位置:缓存数据访问信息
4.访问权限:每个程序访问模式信息
用户视图:持久的数据结构
系统访问接口:
1.字节的集合(UNIX)
2.系统不会关心你想存储在磁盘上的任何的数据结构!
操作系统内部视角:
1.块的集合(块是逻辑转换单元,而扇区是物理转换单元)
2.块大小 <> 扇区大小,在unix中块的大小是4kb
当用户说:给我2-12字节空间时会发生什么
1.返回字节所在的块
2.返回块内对应部分
如果说要写2-12字节呢?
1.获取块,
2.修改块内对应部分
3.写回块
在文件系统中的所有操作都是在整个块空间上进行的
用户怎么访问文件:
1.顺序访问—按字节依次读取,几乎所有访问都是这种方式
2.随机访问—从中间读写,更快速
3.基于内容访问—通过特征,类似数据库,很少
文件内部的结构:应用系统打开复杂文件,但对操作系统该文件可能很简单
文件内部结构:
无结构:单词,比特的队列
简单记录结构:列,固定/可变长度
复杂结构:格式化文档(MS Word, PDF),可执行文件,。。。
多用户系统中的文件共享是很必要的:
1.访问控制:
谁能获得哪些访问权限;
访问模式:读、写、执行、删除,列举
2.文件访问控制列表(ACL)
<文件实体,权限>
3.unix模式
< root/admin, colleagues, others, read, write, execute >
不同用户层级有不同的权限和访问模式
多用户/客户如何同时访问共享文件:
- 和过程同步算法相似
- 因磁盘I/O 和网络延迟而设计简单
unix文件系统UFS语义:
- 对打开文件的写入内容立即对其他打开同一文件的其他用户可见
- 共享文件指针允许多用户同时读写
会话语义:
- 写入内容只有当文件关闭时可见,类似一个会话
锁:
一些操作系统和文件系统提供该功能
7.目录
文件以目录的方式组织起来
目录是一类特殊的文件,每个目录都包含一张表(name,pointer to file header)
目录和文件的树型结构,早期的文件系统是扁平的(只有一层目录)
层次目录结构,类似树的结构
目录的操作:搜索,创建,删除,枚举,重命名,在文件系统中遍历一个路径
操作系统应该只允许内核模式修改目录:
1.确保映射的完整性,
2.应用程序能够读目录,
怎么存目录中的文件?
1.类似一个集合,文件名的线性列表,包含指向数据块的指针(编程简单、执行耗时)
2.或者HASH表等等,hash数据结构的线性表,减少目录搜索时间
目录的遍历:
1.名字解析:逻辑名字转换物理资源(如文件)的过程
在文件系统中:到实际文件的文件名(路径)
遍历文件目录直到目标文件
寻找文件:
名字解析,逻辑名字转换成物理资源
绝对路径—>依次查找—> 先读文件头,再读数据块,搜索子项,如此递归
举例:解析“/bin/ls”
1.读取root的文件头(在磁盘固定位置),
2.读取root的数据块,搜索“bin”项
3.读取bin的文件头
4.读取bin的数据块,搜索“ls”项
5.读取ls的文件头
当前工作目录,用缓存查找:
1.每个进程都会指向一个文件目录用于解析文件名,
2.允许用户指定相对路径来代替绝对路径
文件系统挂载:
一个文件系统需要先挂载才能被访问,挂载点在用户看来相当于目录,一个未挂载的文件系统被挂载在挂载点上
8.文件别名
文件别名
两个或者多个文件名关联同一个文件
文件别名实现:
- 硬链接:多个文件项指向一个文件
- 软链接:以快捷方式指向其他文件
- 通过存储真实文件的逻辑名称来实现
如果删除一个有别名的文件会如何?
如果是软链接,这个别名会成为一个空指针
如果是硬链接,可能有一个隐形计数器,删除一次减一,直到为0时才真正删除
其他管理别名方式:Backpointers方案、添加一个间接层
backpointers 反向指针方案:
1.每个文件有一个包含多个backpointers的列表,所以删除所有backpointers
2.Backpointers使用菊花链管理
或者添加间接层,即目录项数据结构,
1.链接-已存在文件的另一个名字(指针)
2.链接处理-根据指针来定位文件
有了链接机制,就可能出现循环
如何保证没有循环呢?
- 只允许到文件的链接,不允许在子目录的链接
- 每增加一个新的链接都用循环检测算法确定是否合理
更多实践:限制路径可遍历文件目录的数量。
9.文件系统种类
文件系统的类别
- 磁盘文件系统 (文件存储在数据存储设备上,如磁盘,例如FAT、NTFS、ext2/3、ISO9660,等)
- 数据库文件系统(文件根据其特征是可被寻址(辨别)的,例如:WinFS),
- 日志文件系统,记录文件系统的修改/事件,例如journaling file system
- 网络/分布式文件系统(例如:NFS、SMB、AFS、GFS)
- 特殊/虚拟文件系统
- 文件可以通过网络被共享(文件位于远程服务器、客户端远程挂载服务器文件系统、标准系统文件访问转换成远程访问、标准文件共享协议:NFS for Unix,CIFS for Windows)
- 分布式文件系统的问题,辨别用户很复杂,一致性问题,错误处理模式,安全性问题等等
10.虚拟文件系统
分层结构,接口暴露给用户,屏蔽底层差异性,上层是虚拟(逻辑)文件系统,底层是特定文件系统模块
除了设备I/O外,还有网络I/O、等等
虚拟文件系统目的:对所有不同文件系统的抽象
虚拟文件系统的功能:
- 提供一致的文件和文件系统接口
- 管理所有文件和文件系统关联的数据结构
- 高效查询例程,遍历文件系统
- 与特定文件系统模块的交互
基本数据结构:
- 卷控制块,总的,superblock,每个文件系统一个,块,块大小,空余块,计数/指针等
- 文件控制块:VNODE/INODE, 单个文件一个,文件的详细信息 ,许可、拥有者、大小、数据块位置等
- 目录节点:dentry,每个目录项一个,将目录项数据结构及属性布局编码成树型数据结构,指向文件控制块、父节点、项目列表等
数据持续存储在二级存储中,当需要时加载进内存
1.卷控制块:文件系统挂载时进入内存
2.文件控制块:文件被访问时进入内存
3.目录节点: 在遍历一个文件路径时进入内存
11.数据缓存
数据块缓存:
1.数据块按需读入内存(提供read()操作、预读:预选读取后面的数据块)
2.数据块使用后被缓存(假设数据将会再次被使用、写操作可能被缓存和延迟写入)
3.两种数据块缓存方式,缓存的粒度 (1.普通缓冲区缓存 2.页缓存:统一缓存数据块和内存页)
分页要求—当需要一个页的时候才将其载入
按照内存的读写来操作,支持存储,一个页(在虚拟地址空间中)可以被映射到一个本地文件中(二级存储)
文件数据块的页缓存
1.在虚拟内存中文件数据块被映射成页
2.文件的读/写操作被转换成对内存的访问
3.可能导致缺页、脏页
4.相应算法,尽量减少对硬盘的读写次数,类似之前的算法
主存储器(Main memory),简称主存。是计算机硬件的一个重要部件,其作用是存放指令和数据,并能由中央处理器(CPU)直接随机存取。
二级存储(secondary storage,auxiliary storage)是计算机主存储器或内存之外的所有可访问数据存储器。
二级缓存(L2 CACHE)是处理器内部的一些缓冲存储器。它分内部和外部两种芯片:内部的芯片二级缓存运行速度与主频相同,而外部的二级缓存则只有主频的一半。
由于一级缓存容量的限制,为了再次提高CPU的运算速度,在CPU外部放置一高速存储器,即二级缓存。
12.打开文件的数据结构
1.打开文件描述(每个被打开的文件一个、文件状态信息、目录项、当前文件指针、文件操作设置等)
2.打开文件表(一个进程一个、一个系统级的、每个卷控制块也会保存一个列表、所以如果有文件被打开将不能被卸载)
共享机制:强制和劝告(进程可以查找锁的状态来决定)。
13.文件分配
要应对不同大小的文件
大多数文件都很小:
1.需要对小文件提供强力的支持
2.块空间不能太大
一些文件非常大:
1.必须支持大文件(64-bit 文件偏移)
2.大文件访问需要相当高效
如何为一个文件分配数据块:
1.连续分配
2.链式分配
3.索引分配
评价指标:
1.时间高效(如访问速度)
2.空间高效(如存储利用,外部碎片)
连续分配:
文件头指定起始块和长度
位置/分配策略(最先匹配,最佳匹配),类似内存的分配
优点:文件读取表现好,高效的顺序和随机访问
劣势:碎片,文件增长问题(预分配,按需分配),类似数组
最好用于只读文件
链式分配:
以数据块链表方式存储,文件头包含了到第一块和最后一块的指针
优点:创建,增大缩小容易,没有碎片
缺点:不可能真正地随机访问,可靠性(破坏一个链然后整个文件都崩了)
索引分配:
每个磁盘块(索引项),为每个文件创建一个名为索引数据块的非数据数据块(到文件数据块的指针列表)
文件头包含了索引数据块
优点:创建,增大缩小都很容易,没有碎片,支持直接访问
缺点:当文件很小时,存储索引的开销,如何处理大文件?
大文件采用分层的方式,类似内存管理的思想:
- 链式索引块
- 多级索引块,文件头包含多个指针
14.空闲空间列表
跟踪在存储中的所有未分配的数据块
空闲空间列表存储在哪里?
用位图代表空闲数据块列表
11111001111,如果i = 0 代表数据块为空闲
空闲空间列表的最佳数据结构是什么样的?
假设空闲空间在磁盘中均匀分布,那么找到空闲数据块前需要扫描n/r
n —-磁盘上数据块的总数
r —- 空闲块的总数
为了一致性,需要保护
位图必须保存在磁盘上,不允许block在内存中的状态为1而在磁盘中为0
需要在硬盘中完成把Block置为1之后再真正分配
15.多磁盘管理-RAID
raid:
磁盘通过分区来最大限度减小寻道时间,一个分区是一个柱面的集合,各个分区逻辑上独立。
分区:硬盘磁盘的一种适合操作系统指定格式的划分
卷:一个拥有一个文件系统实例的可访问的存储空间
通常常驻在磁盘的单个分区上
使用多个并行磁盘来增加吞吐量,冗余使其可靠性和可用性增加,实现高效存储。
RAID 冗余磁盘阵列
实现:
1.在操作系统内核:存储/卷管理
2.RAID硬件控制器(I/O)
16.磁盘调度