操作系统中文件系统的实现和分配方式探析(下)

操作系统,文件系统,实现,分配,方式,探析 · 浏览次数 : 129

小编点评

**非连续空间存储方式** 非连续空间存储是一种存储文件的方式,它不基于连续的存储技术,而是通过将文件块存储在不同的内存位置来实现高效的存储和访问。 **链式分配** 链式分配是一种非连续空间存储方式,用于为文件分配非连续的磁盘块。它使用两种方法来实现文件分配:显示链接和隐式链接。 * **隐式链接**是一种通过存储头节点和尾节点指针的方式实现文件的非连续分配。 * **显示链接**是一种通过创建指向下一个节点的指针的链表的方式实现文件的非连续分配。 **索引分配** 索引分配是一种通过为每个文件创建索引数据块来实现文件的非连续分配的技术。索引数据块包含指向文件数据块的指针列表,可以快速找到对应的数据块。 **区别** | 特征 |链式分配 | 索引分配 | |---|---|---| | 文件分配方式 | 显示链接 | 隐式链接 | | 查找效率 | 低 | 高 | | 文件扩展支持 | 不支持 | 支持 | | 碎片问题 | 存在 | 不存在 |

正文

非连续空间存放方式

我们已经对连续分配的方式有了一定的了解,并且也清楚了它存在的问题和局限性。为了解决这些问题,非连续存放的方式应运而生。非连续空间存储大致可以分为两种形式:链表形式和索引形式。

链式分配

链式分配是一种离散分配的方式,用于为文件分配非连续的磁盘块。它有两种分配方式:显示链接和隐式链接。

隐式链接

隐式链表分配与我们已知的Java链表知识基本是一致的,都需要存储下一个节点的指针。但为什么称之为隐式链接呢?因为我们不知道每个节点的指针是什么,只有通过遍历的方式从头节点开始逐步获取下一个节点的指针。每次操作都是相同的,指针并没有存储起来。在隐式链接分配中,目录项只存储了头节点(磁盘块)指针和尾节点(磁盘块)指针。当需要分配新的磁盘块时,我们使用最后一个磁盘块中的指针指向新的磁盘块,并将新的磁盘块标记为最后一个磁盘块。

image

现在让我们考虑一个问题:使用隐式链接如何将逻辑块号转换为物理块号?我们可以将其类比为Java中的链表如何找到相应的元素。

当用户提供要访问的逻辑块号 i 时,操作系统需要找到所需访问文件的文件控制块(FCB)。从FCB中我们可以得知文件的起始块号,然后将逻辑块号 0 的数据读入内存,通过这个可以知道逻辑块号 1 的物理块号,然后再读入逻辑块号 1 的数据进入内存,如此类推,最终可以找到用户所需访问的逻辑块号 i。因此,访问逻辑块号 i 需要进行 i + 1 次磁盘 I/O 操作。隐式链接分配就像Java中的链表一样只能按顺序访问,不支持随机访问,因此查找效率较低。

现在让我们考虑另一个问题:使用隐式链接是否方便文件扩展?我们可以将其类比为Java中的链表是否方便进行扩容呢?

我们知道,目录项中存储了结束块号的物理地址。因此,如果要扩展文件,我们只需要将新分配的磁盘块挂载到结束块号的后面。我们修改结束块号的指针指向新分配的磁盘块,并更新目录项。隐式链接分配类似于Java中的链表,很方便进行文件扩展。所有的空闲磁盘块都可以被利用,没有碎片问题,存储利用率较高。

显式链接

有隐式连接那么就有显式链接,隐式链接我们说了没有存储各个节点指针所以每次都需要重新从头结点来获取下一指针节点,那么显示链接是把用于链接各个物理块的指针显式地存放在一张表中,该表称为文件分配表(FAT,File Allocation Table)。

image

由于查找记录的过程是在内存中进行的,从而显著提高了检索速度并减少了访问磁盘的次数。但也正是整个表都存放在内存中的关系,它的主要的缺点是不适用于大磁盘。

举个例子,假设有一个拥有200GB空间和1KB块大小的磁盘。根据显式链接的方式,需要在文件分配表中存储2亿项,每一项对应磁盘上的一个块。如果每一项需要4个字节的存储空间,那么文件分配表将占用800MB的内存。显然,对于大磁盘而言,这种方式并不适合。

索引分配

理解索引分配之前,可以先想一下MySQL中的索引结构,这样可以更好的理解索引分配的原理。

链表的方式解决了连续分配的磁盘碎片和文件动态扩展的问题,但是不能有效支持直接访问(FAT除外)。为了解决这个问题,可以采用索引的方式。

索引的实现是为每个文件创建一个「索引数据块」,里面存放的是指向文件数据块的指针列表,类似于书的目录。通过查阅索引数据块,可以快速找到对应的数据块。

此外,文件头还需要包含指向「索引数据块」的指针。这样可以通过文件头知道索引数据块的位置,然后通过索引数据块里的索引信息找到对应的数据块。

当创建文件时,索引块的所有指针都被设置为空。当首次写入第 i 块时,从空闲空间中获取一个块,并将其地址写入索引块的第 i 个条目。这样,通过文件头中的指向索引数据块的指针,可以知道索引数据块的位置,并通过索引数据块中的索引信息找到对应的数据块。

image

索引分配的优点包括:

  • 创建、增大和缩小文件都很方便;
  • 没有碎片问题;
  • 支持顺序读写和随机读写。

然而,索引分配也有一些缺点。由于索引数据也需要存放在磁盘块中,如果文件很小,实际上只需要一个块就可以存放,但仍需要额外分配一个块来存放索引数据,这会带来额外的开销。

如果文件很大,以至于一个索引数据块无法容纳全部的索引信息,我们可以采用组合的方式来处理大文件的存储。

组合方式是链表 + 索引,也被称为「链式索引块」。在这种实现方式中,索引数据块中会预留一个指针,用于存放下一个索引数据块的地址。当一个索引数据块的索引信息用完时,可以通过该指针找到下一个索引数据块的信息。然而,这种方式也会面临链表方式的问题,即如果某个指针损坏了,后续的数据将无法读取。

image

为了解决这个问题,可以采用多级索引的方式。多级索引将一个大文件的索引信息分散到多个索引数据块中,以减轻单个索引数据块的负担。类似于MySQL的B+树索引结构,多级索引也在非叶子节点存储了索引数据,而索引指针指向叶子节点的数据。尽管存在一些不同,但它们的逻辑是相似的。

image

总结

非连续空间存放方式是为了解决连续分配方式的问题和局限性而提出的。其中,链式分配方式包括隐式链接和显式链接两种形式。隐式链接通过存储头节点和尾节点指针的方式实现文件的非连续分配,但查找效率较低且不支持随机访问,但方便文件扩展且没有碎片问题。显式链接通过文件分配表存储物理块的指针,提高了检索速度但不适用于大磁盘。

索引分配方式则通过为每个文件创建索引数据块,并在文件头和索引数据块中存储指针信息,实现了文件的非连续分配和直接访问。索引分配的优点包括方便创建、扩展和缩小文件,没有碎片问题,支持顺序和随机读写。然而,索引分配也存在一些缺点,如对小文件的额外开销。

为了解决大文件存储问题,可以采用链式索引块和多级索引的组合方式。链式索引块通过指针连接多个索引数据块,但可能面临指针损坏导致数据无法读取的问题。多级索引将大文件的索引信息分散到多个索引数据块中,提高了文件系统的性能和可靠性。通过这些优化,可以更好地处理大文件存储,并提高文件系统的效率。

与操作系统中文件系统的实现和分配方式探析(下)相似的内容:

操作系统中文件系统的实现和分配方式探析(下)

本文介绍了非连续空间存放方式中的两种常见形式:链式分配和索引分配。链式分配通过链表的方式实现了文件的非连续分配,其中包括了隐式链接和显式链接两种方式。隐式链接通过遍历链表来获取下一个节点的指针,适合于文件的扩展,但查找效率较低。显式链接则将指针存储在文件分配表中,提高了检索速度,但不适用于大磁盘空间。索引分配通过为每个文件创建索引数据块,实现了文件的非连续分配和直接访问。多级索引和链式索引块是处理

操作系统中文件系统的实现和分配方式探析(上)

本文主要讨论了操作系统中文件系统的实现和分配方式。首先介绍了虚拟文件系统(VFS)作为中间层,统一了不同文件系统的接口。然后介绍了文件的物理结构,包括文件块和逻辑块之间的映射关系。接着详细讨论了连续分配方式的特点和优缺点,包括顺序访问和随机访问的效率,以及磁盘空间碎片和文件长度扩展不方便的问题。最后提到了非连续分配方式来解决连续分配方式的问题,并留下了下次讨论的悬念。文件系统的实现和分配方式对于操作系统的性能和可靠性都有重要影响,因此深入理解和研究文件系统的原理和机制是非常有价值的。

解密Linux中的通用块层:加速存储系统,提升系统性能

本文探讨了Linux操作系统中的通用块层和存储系统I/O软件分层的优化策略。通用块层作为文件系统和磁盘驱动之间的接口,通过排队和调度I/O请求,提高磁盘的读写效率和可靠性。存储系统的I/O软件分层包括文件系统层、通用块层和设备层,它们相互协作,实现对存储系统的高效管理和操作。本文旨在深入了解通用块层和其他I/O软件层的功能和作用,分析优化存储系统的管理和操作,提升系统性能和可靠性。

[转帖]iozone - 性能压力测试工具

《存储工具系列文章》主要介绍存储相关的测试和调试工具,包括不限于dd、fio、vdbench、iozone、iometer、cosbench等性能负载工具,及strace等调试工具。 1 概述 IOzone是一个文件系统的benchmark工具,可以测试不同的操作系统中文件系统的读写性能。可以测试

[转帖]Linux 6种网络IO模型

https://www.jianshu.com/p/c5aa9197ecf4 背景 大多数文件系统的默认 IO 操作都是缓存 IO,又被称作标准IO。在 Linux 的缓存 IO 机制中,操作系统会将 IO 的数据缓存在文件系统的页缓存(page cache )中,也就是说,数据会先被拷贝到操作系统

[转帖]linux系统下grub.cfg详解和实例操作

linux系统下grub.cfg详解和实例操作 简介 grub是引导操作系统的程序,它会根据自己的配置文件,去引导内核,当内核被加载到内存以后,内核会根据grub配置文件中的配置,找到根分区所使用的文件系统对应的驱动,通过根分区文件系统对应的驱动,挂载根分区,从而达到启动操作系统的目的。 特殊变量

[转帖]天融信专用运维管理系统(专用计算平台版)V1.0 服务器客户端

是否国产 是 基本功能 用于专用信息设备运行状态数据的采集、分析和异常状态告警。产品包含管理端软件和客户端程序。主要功能包括:1、资产管理与状态采集:支持将用户网络中所有专用信息设备纳入资产管理,基于专用数据采集协议持续收集分析资产对象的操作系统、处理器、内存、文件系统分区、、磁盘I/O、网络接口的

[转帖]关于Linux操作系统中LUN的队列深度(queue_depth)

Linux中的queue_depth(队列深度),可以用lsscsi查看。不过今天在我的vm 虚拟机环境中(无外界存储),是没有lsscsi命令。不过,从网上,搜到了如下的信息:$ lsscsi -l[0:0:1:0] disk FUJITSU MAM3184MP 0105 /dev/sda sta

深入理解操作系统中进程与线程的区别及切换机制(下)

本文首先介绍了进程的控制结构,即进程控制块(PCB),它是表示进程的数据结构,包含了进程的相关信息和资源。PCB之间通过链表连接,形成就绪队列和阻塞队列,用于进程调度和资源管理。接着,文章详细探讨了进程的切换过程。进程切换是为了保证公平分配CPU时间片,涉及保存和恢复进程的执行上下文、更新进程状态和调度算法选择等步骤。文中还提到了进程上下文切换的场景,如时间片用完、内存不足、高优先级进程需求等。最

深入理解操作系统中进程与线程的区别及切换机制(上)

进程是正在运行的程序的实例,它可以包含一个或多个线程。我们了解了进程的执行方式,包括早期单核处理器上的顺序执行以及引入多任务概念实现的伪并行。我们还探讨了进程的状态模型。进程可以处于就绪、运行、阻塞和结束等不同的状态。就绪状态表示进程已经准备好运行,但还没有被调度执行。运行状态表示进程正在执行。阻塞状态表示进程被阻塞,需要等待某些事件的发生才能继续执行。结束状态表示进程已经完成执行。