[现代操作系统笔记][第四章文件系统]

第四章 文件系统

4.1 文件

用户角度来考察文件。用户如何使用文件文件有那些特性。

4.1.1 文件命名

文件一种抽象机制,提供了一种在磁盘上保留信息而且以后方便读取的方法。

  • 有的文件系统区分大小写,有的则不区分

    • Unix是前者,MS-DOS是后者
  • FAT-16,FAT-32,NTFS
    • FAT-16(File Allocation Table,文件配置表) : Windows 95
    • FAT-32 : Windows 98
    • NTFS(New Technology File System,新技术文件系统):之后所有Win系列的文件系统

4.1.2 文件结构

文件可以有很多构造方式,列出常用的三种方式。

  • 字节序列

    • 操作系统所见的就是字节,任何含义只在用户程序中解释。
    • UnixWinodws都是用这种方式。
  • 记录序列
    • 读和写都是以记录为单位
    • 80列的穿孔卡片还是主流的时候。
      • 80个字符 = 一个记录。
    • 现在已经没有这种方式了。
    • 类似与mapkey-value对,并利用平衡树来维护key值。

      • 以便能快速查找key值。
    • 在一些处理商业系统的大型计算机受到欢迎

4.1.3 文件类型

普通文件(regulr file):包含用户的信息

  • ASCII文件

    • 由多行正文组成

      • Unix系统每行以换行符(/n)结束。
      • Win系统采用回车符(/r)和换行符(/n)。
    • 优势
      • 可以显示和打印,可以用文本编辑器编辑。
      • 作为其他程序的输入或输出。
  • 二进制文件
    • 具有一定的内部结构,使用该文件的程序才了解这种结构。


目录(directory):管理文件系统结构的系统文件。


4.1.4 文件存取

  • 顺序存取(sequential access)

    • 早期操作系统只有这一种方式。

      • 比如你要读adsadasdsaxdas中第7位,必须从头开始找到第7位。
      • 效率极低,但是适合磁带的工作方式。现在已被淘汰。
  • 随机存取文件(random access file)
    • 能够以任何次序读取其中字节或记录的文件。
    • 两种方式指示从哪里读取文件。
      • 第一种:: read操作中给出开始读文件的位置。
      • 第二种 : 维护一个文件位置。利用seek设置。

4.1.5 文件属性

与文件相关的信息,如创建日期,大小等。这些信息称为文件属性(attribute),有些人称之为元数据(metadata)

  • 前4个属性与文件保护相关。
  • 标志位
  • 时间字段
  • 大小字段

4.1.6 文件操作

  • creat
  • delete
  • open
    • 把文件属性和磁盘地址表装入内存。
  • close
    • 关闭文件释放内部表空间。
  • read
  • write
  • append
  • seek
  • get attributes
  • set attributes
  • rename

4.1.7 使用文件系统调用的示例程序。

完成了copyfile abc xyz的操作

4.2 目录

目录本身也是文件

4.2.1 一级目录系统

目录系统最简单形式就是一个目录包含所有的文件。

  • 诸如电话,数码相机以及一些便携式音乐播放器使用

4.2.2 层次目录系统

4.2.3 路径名

  • 绝对路径

    • 一定以分隔符开头

      • WIN:\
      • Unix:/
      • MULTICS: >
  • 相对路径
    • 必须要和工作目录一起使用。
    • 几个特殊的符号
      • . : 当前目录
      • .. :上一层目录
      • ~ : Linux中自己用户的根目录
      • ~user: Linuxuser的根目录
      • - : Linux中上一次最近访问的目录

4.2.4 目录操作

  • creat
  • delete
  • opendir
  • closedir
  • readdir
  • rename
  • link
    • 连接技术允许在多个目录出现同一文件。
    • 增加该文件的i节点计数器的个数(记录含有该文件的目录树目)。
    • 有时称为硬连接(hard link)
      • 硬链接不占用磁盘空间
      • 硬链接只能作用于文件,不可跨越分区。
      • 硬链接和原来的文件没有什么区别,而且共享一个 inode 号。
      • 硬连接是完全平等的,都掌控的真实的,而不是一个快捷方式。
  • unlink
    • 删除连接文件。
    • Unix中,用于删除文件的系统调用实际上就是unlink
  • 符号连接 : 类似于快捷方式,又叫软连接
    • 可以跨越磁盘的界限
    • 速度较慢

4.3 文件系统的实现

实现者的角度考察文件

4.3.1 文件系统布局

文件系统存放在磁盘

  • 多数磁盘被划分为一个或多个分区

    • 每个分区都有独立的文件系统。
  • 磁盘的0号扇区称为主引导记录(Master Boot Record,MBR),用来引导计算机。
  • MBR的结尾是分区表
    • 该表给出了每个分区的起始和结束地址。
    • 表中的一个分区被标记为活动分区


在计算机被引导的时候

  • BIOS读入并执行MBR
  • MBR做的第一件事是确定活动分区,读入它的第一个块,叫做引导块(boot block),并执行之。
  • 引导块中的程序将装载该分区中的操作系统
    • 为了统一起见,所有分区的开始都是引导块,即使没有操作系统。


之后的磁盘分区的布局随着文件系统的不同而变化。以上是一个可能的布局。

  • 第一个是超级块(superblokc)

    • 超级块包含文件系统的所有关键参数。

      • 确定文件类型用的魔数
      • 文件系统数据块的数量。
      • 其他重要管理信息。
    • 计算机启动,或文件系统首次使用时,超级块被读入内存。
  • 文件系统空闲块的信息。
    • 可以用位图或指针列表给出。
  • 可能有 i节点
    • 是一个数据结构数组,每个文件一个。
    • i节点说明了文件的方方面面。
  • 根目录
  • 文件和目录

4.3.2 文件的实现

文件存储实现的关键问题

  • 记录各个文件分别使用那些磁盘块

1.连续分配

malloc的动态存储分配是一模一样的模型。(但是malloc可以忽视这几个缺点)

优点:

  • 实现简单

    • 只需记录文件的磁盘地址文件的块数
  • 读性能好
    • 只需一次查找,之后不需要寻道旋转延迟。
    • 数据以磁盘全带宽的速率输入。

缺点:

  • 外部碎片太多,需要维护一个空闲列表来存储文件。

    • 但是为了能在空闲列表中找到一个合适的块

      必须要知道文件最终的大小

  • 大多数时候对于文本文档不知道文件的最终大小,所以这是一个硬伤。

使用场景

  • 存在这种情形,文件的大小都事先知道,后续使用中,也不会被改变

    CD-ROM文件系统。

  • DVD的文件系统

多年前,连续分配由于其简单和高性能被实际用于在磁盘文件系统中,后来由于讨厌在文件创建时不得不指定最终文件的大小,这个想法被放弃了。但是随着CD-ROM,DVD以及其他一次性写光学介质的出现,突然间连续分配又成为了一个好主意。所以研究具有清晰和简洁概念的老式系统和思想是很重要的,因为它们有可能以一种令人吃惊的方式在未来系统中得到使用。

2.链表分配

优点:

  • 充分利用了每个磁盘块。
  • 也只需要存放首地址

缺点

  • 随机读的复杂度是O(n),太慢。
  • 指针占去了一些字节,使得存储数据的字节数不再是2的整数次幂
    • 程序都是以2的整数次幂来读写磁盘块,要读一个完整的块,可能要两个磁盘块拼接。

      使得速度变慢

3. 在内存中采用表的链表分配

取出每个磁盘的指针字,把它放到内存的一个表中。这个表叫做文件分配表(File Allocation Table,FAT).

优点:

  • 解决上述链表的两个缺点。

    • 对于随机读写,因为在内存中,即使O(n)也是可以接受的。
    • 存储数据是2的整数次幂了。

缺点:

  • 对于200GB的磁盘和1KB大小的块,这张表需要2亿项,每个表项4字节

    这张表要占600800MB的内存,不太实用

  • 所以FAT对于大磁盘不适用

4. i结点

每个文件赋予一个称为i节点(index-node)的数据结构

  • 其中列出文件属性文件块的磁盘地址

优势

  • 只有在文件打开的时候,i节点才载入内存。

    • 与磁盘总大小无关,只与打开的文件有关。
  • 类似虚拟地址空间的多级页表的方式。

    • i节点里的地址就是一级页表
    • 最底层的地址才是实际的磁盘地址
    • 便于索引,节约空间,完美。

缺点:貌似没有

4.3.3 目录的实现

目录项

打开文件,操作系统利用用户给出的路径名找到相应目录项

  • 目录项提供了查找文件磁盘块所需要的信息。

    • 因系统而异

      • 有可能是磁盘地址+长度(对于连续分配)
      • 有可能是第一块的地址(对于链表来说)
      • i节点号
  • 无论如何,目录系统的主要功能是把ASCII文件名映射成定位文件数据所需的信息。

文件属性

与此密切相关的问题是在何处存放文件属性

  • 一种显而易见的方法是把文件属性直接存放在目录项中。(对应于Windows)
  • 对于采用i节点的系统,还可以把文件属性存到i节点中,而不是目录项中。

文件长度

现代操作系统都支持可变长度长文件名,它们是如何实现的。

  • 第一种,最简单的固定一个255字节的文件名,很浪费空间不考虑。

  • 第二种,就是图4-15(a) ,被后面那种完爆就不提了。
  • 第三种,利用来维护文件名。
    • 每个目录项自身都有固定长度。
    • 的维护跟 malloc的类似。
    • 缺点
      • 一个目录项可能会分布在多个页面里。

        因此处理文件名还是可能有页面故障。

查找文件名

  • 利用哈希表

    • 我的老本行就不要介绍了。
  • 利用高速缓存

4.3.4 共享文件

文件系统本身是一个有向无环图(DAG)而不是一棵树。

有种方式共享(连接)

  • 硬链接

    • 目录指向i节点,并计数
    • 只有当计数被置为0的时候,才真正被删除。
  • 软连接(符号连接)
    • 创建一个类型为LINK的文件,并把该文件放在B下。

      • 里面存储了实际的 连接文件位置
    • 访问文件,需要额外的开销

复制时的问题

如果允许复制时不保留连接的话 (cp 没有-d)

  • 软连接,直接复制所指向文件本身。
  • 硬链接,复制过来后,重置i-node的计数器。

4.3.5 日志结构文件系统(看不下去了,翻译的太烂了)

日志结构文件系统(Log-structured File System,LFS)设计的主要原因是

  • CPU的运行速度越来越快,RAM内存容量变得更大,磁盘高速缓存也在增加。

    • 不需要磁盘访问操作,就能完成很大一部分读请求。
    • 未来多数的磁盘访问操作是写操作。
      • 写操作往往是零碎的。
      • 一个50us的磁道写操作需要10ms的寻道和4ms的旋转延迟操作。磁盘的效率降低到1%

零碎的写操作来源于哪里?假设写入一个新建的文件

  • 写该文件目录的i节点,目录块。
  • 文件的i节点,以及文件本身。

这些写操作很慢,如果在写操作完成之前死机。

  • 造成文件系统的严重不一致性。

4.3.6 日志文件系统

保存一个用于记录系统下一步将要做什么的日志

  • 即使奔溃后,也能通过日志来继续处理。
  • 微软的NTFS,ext3ReiserFS文件系统都是用日志。

4.3.7 虚拟文件系统(翻译太烂,看不完)

即使在同一计算机下同一操作系统,也会使用不同的文件系统。

Windows

Windows通过指定不同的盘符来处理这些不同的文件系统,比如C:D:等。

盘符是显示存在的,所以Windows知道传递什么样的文件系统请求。

不需要将不同类型文件整合同一模式。

Unix

相比下,所有现代的UNIX系统做了一个很认真的尝试,将多个文件系统整合到一个统一的结构中。

觉得大多数UNIX操作系统使用虚拟文件系统(Virtual File System,VFS)来将文件系统统一。

4.4 文件系统管理和优化

4.4.1 磁盘空间管理

几乎所有的文件系统都把文件分割成固定大小的来存储,各块之间不一定相邻(页式管理)。

块大小

一旦确定把文件按固定大小的块来存储,就会出现一个问题,块的大小应该是多少?

过大的块(空间利用低)

  • 小的文件浪费大量磁盘空间,内部碎片严重。

过小的块(时间利用低)

  • 大多数文件都会要有多个块,需要多次寻道旋转延迟才能读完这个文件,性能太低。

观点

  • 历史观点来说,文件系统将大小设在1~4KB之间。(历史时期磁盘数量少,空间利用率更重要)。
  • 随着磁盘超过1TB,可以通过将块的大小提升到64KB接收磁盘的浪费,增加时间性能。
    • 现代基本不可能出现磁盘空间短缺的状况。

记录空闲块

  • 磁盘块链表

    • 通常情况下,采用空闲块来存放空闲表
    • 内存中保存一个指针块
      • 文件创建时,所需要的块从执政块中取出来。

        • 如果指针块用完了,从磁盘读入一个新的指针块。
      • 文件删除是,其磁盘块被释放,并添加到指针块
        • 指针块填满后,将它写入磁盘。
      • 避免不必要的I/O,(即有利于创建,也有利于写)
        • 在内存中保留一个半满的指针块,其余大多数为的状态
  • 位图
    • n个块的磁盘需要n位位图

      • 空闲块用1表示
      • 已分配块用0表示
    • 位图所需要的空间很少。
    • 隐形好处,保证很有可能存储会比较紧密,减少磁盘壁的移动。
    • 缓存
      • 由于位图是一种固定大小的数据结构,在支持分页的内核

        可以直接存放到虚拟地址空间,等待需要的时候进行页面的调入

磁盘配额

现在应该没人用这个技术了。。。

4.4.2 文件系统的备份(略过)

几个问题

  • 一:备份那些数据?
  • 二:对前一次已经备份过但没有修改过的再备份十分浪费。
  • 三:是否压缩?
  • 四:对还在活动的文件系统做备份是很难得。
  • 五:备份会引入非技术问题(间谍?)

4.4.3 文件系统的一致性

影响文件系统的可靠性的另一个问题是文件系统的一致性

  • 修改过的磁盘块全部写回之前系统崩溃,可能使文件系统处于不一致状态

为了解决文件系统的不一致问题,很多计算机都带有一个实用程序以检验文件系统的一致性。

  • UnixfsckWindowsscandisk.
  • 一般在崩溃重启后,都可以选择性运行。

我们介绍一下Unixfsck的原理。

  • 块的一致性检查
  • 文件的一致性检查

4.4.4 文件系统性能

  1. 高速缓存

    • 块高速缓存
    • 缓冲区高速缓存
    • 存储器映射
  2. 块提前读
    • 只能加速顺序存取方式
    • 随机存取方式,效率更低。
  3. 减少磁盘臂运动
    • 空闲块的分配减少磁盘臂运动

      • 使用位图
      • 空闲表使用块簇技术。
    • i节点的优化
      • 读取一个很短的文件,也需要先两次磁盘访问

        • 读取i节点
        • 读取访问块
        • 两者之间的访问增加寻道时间。
      • 改进
        • 第一种。磁盘中部存放i节点。
        • 第二种。磁盘分为多个柱面组,每个柱面组有自己的i节点

4.4.5 磁盘块整理

Win

磁盘性能可以这样恢复

  • 移动文件使它们相邻,把所有的空闲空间放在一个或多个大的连续空间。
  • windowsdefrag从事这个事
    • windows用户应该定期使用。
    • NTFS貌似产生的碎片少很多了

Linux

  • Linux文件系统(ext2,ext3)由于使用i节点的方式,很少需要使用手动的磁盘碎片整理。

4.5 文件系统实例

4.5.1 CD-ROM

4.5.2 MS-DOS

  • FATFAT32现在依旧流行于嵌入式系统。

读文件时

  • MS-DOS调用open系统调用,获得文件的句柄

    • open系统调用识别一个路径。路径是一个一个分量的查找

      直到找到最终的目录读入内存,搜索要打开的文件。

目录项

4.5.3 Unix V7

即便是早期版本的UNIX也是一个相当复杂的多用户文件系统,因为它是MULTICS继承下来的。

时间: 2025-01-31 06:19:25

[现代操作系统笔记][第四章文件系统]的相关文章

Android群英传笔记——第四章:ListView使用技巧

Android群英传笔记--第四章:ListView使用技巧 近期也是比較迷茫.可是有一点点还是要坚持的,就是学习了.近期离职了,今天也是继续温习第四章ListView,也拖了事实上也挺久的了,listview可谓是老牌大将了,非常多的应用场景都要使用它,他也是我们用得最多的控件之中的一个了,尽管如今出来了一个RecyclerView,可是ListView的地位一时半会儿还是撼动不了的.这就促使我们更加应该去把他掌握了 一.Listview经常使用优化技巧 我们一步步来把ListView学习好

《Linux Shell脚本攻略》 笔记 第四章:高效文本处理

<Linux Shell脚本攻略> 笔记 第四章:高效文本处理 1.IP地址的正则表达式: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} 2.grep用法 //在多级目录中对文本进行递归检索 [[email protected] program_test]# grep "yang" ./ -Rn ./test.txt:6:laoyang ./right.txt:1:1 yang man //忽略大小写匹配 [[email pr

人月神话阅读笔记—第四章

人月神话阅读笔记-第四章 ------2016.6.14 概念的完整性是很重要的,为了反应一系列连贯的设计思路,可以省略一些不规则的特性和改进,不提倡独立和无法整合的系统,最需要的是在整体概念上的完整性要求. 获得概念的完整性时,会出现一种情况,编程系统使计算机更加好用,但是功能比较多的时候,软件外部描述就会比系统本身大很多:但是功能太少,不能满足需求,但是都需要满足概念上的完整性. 在进行概念的完整性时,产品设计需要由一个人或者少数几个人来实现,但是对于大型的系统,需要将设计方法.体系结构的工

APUE读书笔记-第四章 文件和目录

到第四章了,不知什么时候才能把这本书看完,耽误的时间太多了. 第四章是在第三章的基础上,主要描述文件系统的其他性质和文件的性质. 4.2 stat.fstat.fstatat.lstat函数 首先来看看这四个函数的原型: #include <sys/stat.h> ///usr/include/x86_64-linux-gnu/sys/ int stat (const char *__restrict __file, struct stat *__restrict __buf) int fst

《Linux内核设计与实现》读书笔记 第四章 进程调度

第四章进程调度 进程调度程序可看做在可运行太进程之间分配有限的处理器时间资源的内核子系统.调度程序是多任务操作系统的基础.通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发执行的效果. 最大限度地利用处理器时间的原则是,只要有可以执行的进程,那么总会有进程在执行. 4.1多任务 多任务操作系统就是能同时并发地交互执行多个进程的操作系统.多任务能使多个进程处于堵塞或者睡眠状态.就是任务位于内存内但是不被执行,直到某一事件发生. 分类: l  非抢占式:除非进程自己主动停止运行

自己动手写操作系统 第四章总结

本章主要内容是建立一个功能比較完好的引导扇区也称为 boot sector 首先回想一下一个操作系统从开机到执行的过程 1.引导 2.载入内核入内存 3.跳入保护模式 4.開始运行内核 可见在内核開始运行前还有非常多工作要做,假设所有交给boot sector,512字节非常可能不够用,所以我们须要将这个 功能分担出来,这个模块就是loader 如今,boot sector 的功能就是负责把loader载入到内存中,而且把控制权交给它,到此,boot sector就完毕任务了 而载入内核的功能就

Java学习笔记—第四章

第四章  变量和常量 1. Java的访问控制修饰符 使用访问控制修饰符可以限制数据的访问权限.访问控制修饰符有4个等级:private.protected.    public和默认(不指定修饰符). 类型/权限 private protected public 默认 所属类 可访问 可访问 可访问 可访问 同一个包中的其他类(包括子类) 不可访问 可访问 可访问 可访问 不同包中的子类 不可访问 可访问 可访问 不可访问 不同包中的非子类 不可访问 不可访问 可访问 不可访问 2. 变量:变

【PMP】Head First PMP 学习笔记 第四章

第四章 项目整合管理 项目经理每天的工作 力保项目顺利进行 紧密监督以确保计划进行 计划本身不完善需要予以修正 即使是更大的项目的子项目,也要有收尾的过程 6个整合管理过程 整合管理划分为6个过程,项目经理必须掌握的核心职责. 1.制订项目章程 授权你展开工作的文档,通常由赞助人(为项目提供资金的人)交给你. 2.制订项目管理计划 项目管理计划涵盖了所有知识领域,很大一部分就是告诉你在出现问题时如何处理变更. 3.指导和管理项目执行 确保所有人都在做他们本该做的事,项目创建的产品和项目确实满足干

《利用python进行数据分析》读书笔记--第四章 numpy基础:数组和矢量计算

第四章 Numpy基础:数组和矢量计算 实话说,用numpy的主要目的在于应用矢量化运算.Numpy并没有多么高级的数据分析功能,理解Numpy和面向数组的计算能有助于理解后面的pandas.按照课本的说法,作者关心的功能主要集中于: 用于数据整理和清理.子集构造和过滤.转换等快速的矢量化运算 常用的数组解法,如排序.唯一化.集合运算等 高效的描述统计和数据聚合/摘要运算 用于异构数据集的合并/连接运算的数据对齐和关系型数据运算 将条件逻辑表述为数组表达式(而不是带有if-elif-else分支