Lecture 21: File Systems 2

回顾:

1. 设备固有特性带来的挑战

  • 由于寻道时间、旋转延迟、传输时间(硬盘驱动器)造成的延迟
  • 用于写页的块擦除(SSDs)

2. 两级性能提升

  • 磁盘调度和柱面斜进
  • 文件系统实现

本章小结:

  • 文件系统层与磁盘布局
  • 文件、目录及操作系统数据结构的实现
  • 可用空间管理、分区、引导扇区等

文件系统

操作系统能为我做什么?

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo1 {
  public static void main(String[] args) throws IOException {
    FileWriter fw =
      new FileWriter(("C:/Program Files (x86)/test.txt"));
    PrintWriter pw = new PrintWriter(fw);
    pw.close();
  }
}
  1. 导入必要的类FileWriterIOExceptionPrintWriter

  2. 主方法:声明可能抛出IOException

  3. 创建FileWriter对象:尝试在路径"C:/Program Files (x86)/test.txt"创建文件

  4. 创建PrintWriter对象:包装FileWriter以便更方便地写入文本。

  5. 关闭资源:调用pw.close(),这会自动关闭底层的FileWriter。

文件系统抽象:将逻辑文件系统映射到物理文件系统(从物理层抽象)
从设备抽象:统一的观点,非常不同的底层存储机制
并发性:如果多个进程同时访问文件怎么办
安全性:为什么拒绝访问

文件系统能够使数据易于存储、定位和检索,且效率高。

磁盘布局

引导(Boot)扇区和分区

磁盘由一系列扇区组成(0 - N)
引导记录(Boot record)位于磁盘的起始位置:

  • 用于启动计算机(BIOS 读取并执行引导扇区)
  • 其末尾包含分区表,其中包含活动分区
  • 一个分区被标记为活动分区,其中包含加载操作系统引导块

磁盘通常被分成多个分区

  • 每个分区可能包含不同的文件/操作系统(有时甚至没有)

磁盘布局

分区布局(取决于文件系统)

包含启动操作系统所需代码的引导块 Boot block(每个分区都包含,无论该分区是否包含操作系统)
包含有关分区信息的超级块 Super block(分区大小、FCB(文件控制块)数量、空闲列表位置等)
空闲空间管理包含指示空闲 FCB(文件控制块)或数据块数据结构
元数据文件控制块(例如 i 索引节点)
数据块,包括根目录(文件系统树的顶部)

文件&目录

操作系统抽象

一种用户视角,通过操作系统提供的抽象(系统调用)来定义文件系统(文件目录
一种实现视角,通过文件系统的底层实现来定义其内容

: User vs. Implementation View

逻辑层(Logical Layers)

共享层:

  • 输入/输出控制(I/O control设备控制器/寄存器(device controller/registers(设备驱动程序、中断处理程序)进行交互
  • 基本文件系统(Basic file system指示设备驱动程序“块”、安排输入/输出操作,并管理(元)数据的缓冲区缓存

特定于文件系统的层:

  • 文件组织(File organisation为文件和可用空间划分逻辑块
  • 逻辑文件系统(Logical file system管理文件控制块目录结构和保护

应用程序(Application programs定义文件的结构

文件系统层

文件(Files)

类型

Windows 和 Unix(包括 OS X)都具有常规文件目录

  • 常规文件ASCII 二进制(定义明确)格式存储用户数据
  • 目录将文件组合在一起(但从实现层面来看,它们也是文件)

Unix 还有字符特殊文件和特殊文件:

  • 字符特殊文件用于模拟串行 I/O 设备(例如键盘、打印机)
  • 块特殊文件用于模拟,例如硬盘

文件是顺序访问、随机(直接)访问和索引访问

文件控制块与表

文件控制块(File control blocks,FCBs)内核数据结构

  • 如果允许用户应用程序直接访问这些控制块,可能会破坏其完整性
  • 系统调用使用户应用程序能够(在内核模式下)请求操作系统为其执行操作

FCB 保存在每个进程系统范围的打开文件(数组)中,通过进程特定的文件句柄进行索引

文件控制块(FCB)

每个进程的文件表包含了与该进程相关的特定信息,例如:

  • 该进程当前打开的所有文件
  • 读/写/当前指针
  • 指向系统级文件表中相关条目的引用

系统级文件表包含一般信息,例如:

  • 每个打开的文件对应一个条目
  • 磁盘上的位置
  • 访问时间
  • 引用计数
File Tables

系统调用

用于文件操作的系统调用包括:创建(create())、打开(open())、关闭(close())、读取(read())、写入(write())等等。例如:
open() 系统调用:

  1. 逻辑名称映射到标识文件控制块底层名称
  2. 从驱动器中获取“FCB”(文件控制块)
  3. 将其添加到进程/系统打开文件表中(增加引用计数
  4. 返回进程特定的文件句柄(表中的索引)

close() 系统调用:

  1. 减少引用计数
  2. 与磁盘同步 FCB
  3. 当引用计数为 0 时,从进程/系统文件表中移除 FCB

示例 使用“strace”(在 MacOS 系统中称为“dtruss”):

# command = strace cat helloWorld.txt > /dev/null

execve("/usr/bin/cat", ["cat", "helloWorld.txt"], 0x7fffccb21658 /* 34 vars */) = 0
...
open("helloWorld.txt", O_RDONLY) = 3
...
read(3, "Hello World\n", 1048576) = 12
write(1, "Hello World\n", 12) = 12
read(3, "", 1048576) = 0 # 再次尝试读取,返回 0 字节(文件结束)
...
close(3) = 0  # 关闭数据文件
close(1) = 0  # 关闭标准输出(/dev/null)
close(2) = 0  # 关闭标准错误
exit_group(0) = ?  # 进程以状态码 0(成功)退出
  • strace cat helloWorld.txt > /dev/null:使用 strace 跟踪 cat 命令的系统调用

  • > /dev/null:将标准输出重定向到空设备(丢弃输出)

execve - 执行程序:

  • 加载并执行 /usr/bin/cat 程序

  • 传递参数:"cat" 和 "helloWorld.txt"

  • 继承 34 个环境变量

  • 返回 0 表示成功

open - 打开文件:

  • 以只读模式打开 helloWorld.txt

  • 返回文件描述符 3(0-2 是标准输入、输出、错误)

read - 读取文件内容:

  • 从文件描述符 3 读取数据

  • 读取到内容:"Hello World\n"(12 个字节)

  • 缓冲区大小为 1048576 字节(1MB)

  • 返回实际读取的字节数:12

 write - 写入输出

  • 向文件描述符 1(标准输出)写入 12 字节

  • 虽然输出被重定向到 /dev/null,但 write 调用仍然执行

  • 返回写入的字节数:12

目录(Directories)

实现

目录是将文件进行分类特殊文件,其结构文件系统定义

  • 一个bit会被设置以表明它们是目录。
  • 它们将人类可读的“逻辑”名称映射到用于文件控制块唯一标识符,这些标识符详细说明了物理位置和文件属性

两种方法

  • 所有属性都存储目录文件中(例如文件名、磁盘地址——Windows)
  • 指向包含文件属性的数据结构(例如 i-节点)的指针(Unix)

目录能够构建有向无环图(directed acyclic-graphs,DAG(是对树形结构的扩展——但链接可能会破坏这种结构)

DAG 目录实现

系统调用

与文件类似,目录也是通过系统调用来进行操作的。

  • create/delete:创建/删除一个新目录
  • opendir、closedir:将目录添加/从内部表中移出
  • readdir:返回目录文件中的下一个条目
  • 其他操作:rename, link, unlink, list, update

常见的操作包括创建、删除、搜索、列出、遍历等等。

例子:文件访问,读取/home/pszgd/COMP2007/helloWorld.txt

#Steps to read /home/pszgd/COMP2007/helloWorld.txt

- read FCB for /
- find FCB location for /home
- read FCB for /home
- find FCB location of /home/pszgd
- read FCB for /home/pszgd
- find FCB location for /home/pszgd/COMP2007
- read FCB for /home/pszgd/COMP2007
- find FCB location for /home/pszgd/COMP2007/helloWorld.txt
- read FCB /home/pszgd/COMP2007/helloWorld.txt
  => update per process/system file tables
- read data for /home/pszgd/COMP2007/helloWorld.txt
- close the file
  => update per process/system file tables

(last access times may need updating on disk)

检索文件归根结底就是要尽可能快速地在目录文件中进行搜索
简单的随机排列目录项可能不够(搜索时间与项的数量呈线性关系)
对于大型目录,可以使用索引或哈希表来实现

空闲空间管理

与内存管理类似,位图和链表也可用于空闲空间管理

位图(Bitmap)

位图通过在映射表中单个位来表示每个块

  • 位图的大小会随着磁盘大小的增加而增加,但对于给定的磁盘而言则是恒定的
  • 位图所占用的空间比链表相对更少
磁盘布局

链表(Linked List

链表中的自由组集合

  • 利用空闲块来保存空闲块的位置(因此,它们不再是空闲的)
  • 链表的大小会随着磁盘的大小而增加随着块的大小而缩小 ①例如,对于 1KB 的块和 32 位/4 字节的磁盘块编号,每个块将容纳 255 个空闲块(一个用于指向下一个块的指针)②由于当磁盘满时自由列表会缩小,所以这并非浪费的空间
  • 块是相互链接的,即多个块列出了可用的块

链表可以通过跟踪每个条目连续空闲块的数量(称为Counting)来进行修改

位图 vs. 链表

位图:

  • 需要额外的存储空间。例如:如果块大小为 2^{12} 字节(4KB),而磁盘大小为 2^{30} 字节(1GB)⇒ 位图大小:2^{30}/2^{12} = 2^{18}(32KB)
  • 仅对于小型磁盘才有可能将其保留在内存中。

链表:

  • 随着空块数量的增加而增长
  • 不会浪费磁盘空间(利用空闲空间)
  • 我们只需在内存中保存一个指向块的指针块(需要时加载新的块)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值