【操作系统】【读书笔记】文件系统实现

文件系统实现

概述

  • 文件系统是纯软件实现
  • 文件系统的两个重点:数据结构、访问方法
    • 如何组织和存储元数据?数组、树等等
    • 如何高性能的访问文件?
    • 心智模型:研究文件系统时,聚焦于核心问题,而不要囿于代码的细节
  • 下面讨论的都是简单文件系统(VSFS)

整体组织

  • 数据区:最重要的部分,真实存储数据的区域

    • 块大小:只用一种块大小,通常4KB
  • inode:文件系统必须记录每个文件的信息,包括:数据块、文件的大小、所有者和访问权限、访问和修改时间等等。因此必须有一块区域存放这些元数据

    • VSFS使用数组存放
  • 记录数据块和inode是否空闲:使用data bitmap和inode bitmap

  • 记录磁盘总体信息:使用Superblock块,记录:文件系统中的剩余inode、数据块数目,inode表的起始地址,幻数(标志文件系统类型)等等

  • 长这样:
    在这里插入图片描述

文件组织:inode

  • 文件的低级名称:简单文件系统中inode存在数组中,则一个inumber(类似数组下标,但是经过平移)对应一个inode,inumber即低级名称(因为inumber和文件一一对应)

    • 可以根据inumber计算出inode的地址
  • inode的内容

    • 文件类型(例如,常规文件、目录等)

    • 大小

    • 分配给它的块数

    • 保护信息(如谁拥有该文件以及谁可以访问它)

    • 一些时间信息(包括文件创建、修改或上次访问的时间)

    • 有关其数据块驻留在磁盘上的位置的信息(如某种类型的指针)

    • ext2的inode:存的东西还是很多的
      在这里插入图片描述

  • 如何存储大文件

    • 多级索引:inode中有一部分索引是直接指针,指向数据区的某些块;还有间接指针,指向包含更多指针的块,每个指针指向数据
      • 双重间接指针:多套一层,可以支持更大的文件范围!
      • 实现:不平衡树
      • 原理:大多数文件很小
    • 基于范围的方法:不需要指向每个块的指针,而是记录起始地址 + 长度
      • 不够灵活,但是更紧凑,适用大文件
    • 基于链接的方法:inode只存一个指针,然后每个数据块的末尾链接下一个数据块
      • 缺点:类似链表,访问尾部、随机访问等等操作难以进行
      • 改进:不把指针信息存在数据块的末尾,而是存在内存的高速缓存中

目录组织

  • 目录也是一种文件!因此完全不影响文件系统的组织,只不过存储的内容稍有不同:

    • VSFS:基本只包含一个二元组(文件名,inode号)。可能还包含一些别的参数,如文件名的长度等等,如下: 在这里插入图片描述

    • 删除文件:会留下一个空白的条目,因此会有一些方法来标记它(如将inode设为0表示空闲)

    • 目录数据的结构:不一定非要是数组,也可以是树或其他的

      • XFS:B树,文件创建操作更快(因为需要搜索目录,确保文件名没有冲突)

空闲空间管理

  • 位图(最棒!)
  • 空闲列表:早期文件系统使用的方法,即链表。超级块中保存第一个空闲块的指针,然后每个空闲块都链接下面的空闲块
  • 预分配策略:创建文件的同时分配一小部分数据块(因为创建文件的下一步大概率就是写),保证部分连续,提高性能

访问路径:读取和写入

  • 所有的遍历都从根开始,因此系统需要知道根的inode号,一般为2

    • 0:保留作为空闲inode的标识
    • 1:跟踪所有的坏块(特殊用途)
  • open函数遍历的过程:读目录文件的inode -> 读目录文件的data -> 读下层目录的inode -> …. -> 找到最终要读的文件的inode号

    • 下一步,取inode信息,对用户权限进行检查。如果没有问题,修改进程的打开文件表,分配文件描述符

    • read读取内容后会修改文件的偏移量(在文件描述符中)

    • 例子:

    • 缺点:io次数与路径长度成正比;对于大型目录,可能需要读取很多数据块才能定位到需要的条目

      • 优化:B树!
  • write写入磁盘的过程:一般都需要分配新数据块,故需要多次io

    • 读、写data的bitmap
    • 读、写inode的bitmap(修改数据块的指针)
    • 真正写入数据块本身
    • 如何降低io的成本?引入高速缓存!

缓存和缓冲

  • 缓冲资源划分方法

    • 静态划分:给定固定大小的内存用作缓存

      • 优点:确保有一定的资源可用,提供可预测的性能,实现简单
      • 缺点:可能导致浪费
    • 动态划分:虚拟内存页面和文件系统页面集成到统一页面缓存中,按需分配

      • 缺点:实现可能比较复杂,可能导致空闲资源被占用,需要使用时花费较长时间回收
  • 为什么要缓存

    • 读操作可以得到极大的优化
      • 第一次读文件时可能需要很多io,但随后如果读取同一目录下的文件,则搜索路径的过程大部分命中缓存,不需要io
    • 写入流量不会减少(因为数据确实都要写入磁盘),但是可以将多个io积累为一批写入,同时部分写操作可能会因为拖延而完全避免
      • 缺点:考虑系统崩溃导致缓存没有写入的问题
  • 特殊情况:某些应用程序(如数据库)不希望写缓冲,可以通过调用fsync()绕过缓存直接io,或者使用原始磁盘接口从而完全避免使用文件系统

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值