《Operating Systems: Three Easy Pieces》学习笔记(三十五) 日志结构文件系统
在 20 世纪 90 年代早期,由 John Ousterhout 教授和研究生 Mendel Rosenblum 领导的伯克利小组开发了一种新的文件系统,称为日志结构文件系统(LFS)。他们这样做的动机是基于以下观察: 内存大小不断增长。 随着内存越来越大,可以在内存中缓存更多数据。随着更多数据的缓存,磁盘流量将越来越多地由写入组成,因为读取将在缓存中进行处理。...
在 20 世纪 90 年代早期,由 John Ousterhout 教授和研究生 Mendel Rosenblum 领导的伯克利小组开发了一种新的文件系统,称为日志结构文件系统(LFS)。他们这样做的动机是基于以下观察: 内存大小不断增长。 随着内存越来越大,可以在内存中缓存更多数据。随着更多数据的缓存,磁盘流量将越来越多地由写入组成,因为读取将在缓存中进行处理。...
文件系统面临的一个主要挑战在于,如何在出现断电(power loss)或系统崩溃(system crash)的情况下,更新持久数据结构。称为崩溃一致性问题(crash-consistency problem)。 一个详细的例子 假定磁盘上使用标准的简单文件系统结构,包括一个 inode 位图(inode bitmap,只有 8 位,每个 inode 一个),一个数据位图(data bit...
问题:性能不佳 传统文件系统的问题: 碎片化,主要是外部碎片导致文件的块分布过于分散,增加了磁盘寻道成本 原始块太小导致的文件被分为太多块,提高了定位成本,因为每读一个块都需要定位一次 FFS:磁盘意识是解决方案 以上问题的原因是把磁盘当作内存看待,过于依赖随机访问,忽视了底层的磁盘寻道特性 组织结构:柱面组 磁盘是由一环环磁道构成,主要的耗时是跨磁道导致的磁头移动(...
本章将介绍一个简单的文件系统实现,称为 VSFS(Very Simple File System,简单文件系统)。它是典型 UNIX 文件系统的简化版本,因此可用于介绍一些基本磁盘结构、访问方法和各种策略,你可以在当今许多文件系统中看到。 整体组织 将磁盘分成块(block),每块大小相同,通常每块为 4 KB 其中一部分作为管理用空间(超级块,位图,inode 结构信息),另一部分作...
操作系统应该如何管理持久存储设备? 文件和目录 存储虚拟化形成了两个关键的抽象。 文件(file) 文件就是一个线性字节数组,每个字节都可以读取或写入。每个文件都有一个与其关联的低级名称(low-level name),通常是某种数字。用户通常不知道这个名字(我们稍后会看到)。由于历史原因,文件的低级名称通常称为 inode 号(inode number)。 目录(director...
简介 本章将介绍廉价冗余磁盘阵列(Redundant Array of Inexpensive Disks),更多时候称为 RAID,这种技术使用多个磁盘一起构建更快、更大、更可靠的磁盘系统。 优点: 性能。并行使用多个磁盘可以大大加快 I/O 时间。 容量。将多个磁盘合并为逻辑上的一个单磁盘。 可靠性。在多个磁盘上传输数据(无 RAID 技术)会使数据容易受到单个磁盘丢...
主要介绍磁盘驱动器HDD(hard disk drive)相关技术,不过现在SSD变成主流了,但HDD因为其数据可靠性和价格在特定的领域依旧不可替代 接口 驱动器由大量扇区(512 字节块)组成,每个扇区都可以读取或写入。在具有 n 个扇区的磁盘上,扇区从 0 到 n−1 编号。因此,我们可以将磁盘视为一组扇区,0 到 n−1 是驱动器的地址空间(address space)。 多扇区...
系统架构 我们先看一个典型系统的架构(见图 36.1)。其中,CPU 通过某种内存总线(memory bus)或互连电缆连接到系统内存。图像或者其他高性能 I/O 设备通过常规的 I/O 总线(I/O bus)连接到系统,在许多现代系统中会是 PCI 或它的衍生形式。最后,更下面是外围总线(peripheral bus),比如 SCSI、SATA 或者 USB。它们将最慢的设备连接到系统,...
基于事件的并发(event-based concurrency),在一些现代系统中较为流行,比如 node.js,但它源自于 C/UNIX 系统,我们下面将讨论。 基于事件的并发针对两方面的问题。一方面是多线程应用中,正确处理并发很有难度。 正如我们讨论的,忘加锁、死锁和其他烦人的问题会发生。另一方面,开发者无法控制多线程在某一时刻的调度(由系统调度)。 基本想法:事件循环 我们使用的...
有哪些类型的缺陷 非死锁缺陷 违反原子性缺陷 违反了多次内存访问中预期的可串行性(即代码段本意是原子的,但在执行中并没有强制实现原子性) Thread 1:: // 判断和赋值应该是原子性的 if (thd->proc_info) { ... fputs(thd->proc_info, ...); ...