• Lec14 File systems 笔记


    文件系统中核心的数据结构就是inodefile descriptor

    分层的文件系统:

    • 在最底层是磁盘,也就是一些实际保存数据的存储设备,正是这些设备提供了持久化存储。
    • 在这之上是buffer cache或者说block cache,这些cache可以避免频繁的读写磁盘。这里我们将磁盘中的数据保存在了内存中。
    • 为了保证持久性,再往上通常会有一个logging层。许多文件系统都有某种形式的logging
    • 在logging层之上,XV6有inode cache,这主要是为了同步(synchronization)
    • 再往上就是inode本身了。它实现了read/write。
    • 再往上,就是文件名,和文件描述符操作。

    在这里插入图片描述

    存储设备层:

    存储设备连接到了电脑总线之上,总线也连接了CPU和内存。一个文件系统运行在CPU上,将内部的数据存储在内存,同时也会以读写block的形式存储在SSD或者HDD

    在这里插入图片描述

    block布局

    从文件系统的角度来看磁盘还是很直观的。因为对于磁盘就是读写block,我们可以将磁盘看作是一个巨大的block的数组,数组从0开始,一直增长到磁盘的最后。

    在这里插入图片描述

    • block0要么没有用,要么被用作boot sector来启动操作系统。
    • block1通常被称为super block,它描述了文件系统。它可能包含磁盘上有多少个block共同构成了文件系统这样的信息。我们之后会看到XV6在里面会存更多的信息,你可以通过block1构造出大部分的文件系统信息。
    • 在XV6中,log从block2开始,到block32结束。实际上log的大小可能不同,这里在super block中会定义log就是30个block。
    • 接下来在block32到block45之间,XV6存储了inode。我之前说过多个inode会打包存在一个block中,一个inode是64字节。
    • 之后是bitmap block,这是我们构建文件系统的默认方法,它只占据一个block。它记录了数据block是否空闲。
    • 之后就全是数据block了,数据block存储了文件的内容和目录的内容。

    inode

    这是一个64字节的数据结构。

    • type字段,表明inode是文件还是目录。
    • nlink字段,也就是link计数器,用来跟踪究竟有多少文件名指向了当前的inode。
    • size字段,表明了文件数据有多少个字节。
    • 12个block编号,这12个block编号指向了构成文件的前12个block
    • indirect block number,它对应了磁盘上一个block,这个block包含了256个block number,这256个block number包含了文件的数据

    在这里插入图片描述

    目录(directory)

    每个entry是16个字节

    • 前2个字节包含了目录中文件或者子目录的inode编号,
    • 接下来的14个字节包含了文件或者子目录名。

    在这里插入图片描述

    File system工作流程

    • 启动XV6的过程中,调用了makefs指令,来创建一个文件系统。makefs创建了一个全新的磁盘镜像,在这个磁盘镜像中包含了我们在指令中传入的一些文件
    • XV6会打印出文件系统的一些相关信息,其中包括了
      • boot block
      • super block
      • 30个log block
      • 13个inode block
      • 1个bitmap block
      • 954个data block

    echo “hi” > x的文件系统调用过程

    输出对哪些block做了写操作
    在这里插入图片描述

    第一阶段是创建文件

    write 33:type字段从空闲改成了文件,并写入磁盘表示这个inode已经被使用了
    write 33:写入inode的内容,包含linkcount为1以及其他内容。
    write 46 :向第一个属于根目录的data block写数据,增加了一个新的entry,其中包含了文件名x,以及我们刚刚分配的inode编号。
    write 32: 修改标识根目录的大小的数据
    write 33: 更新了文件x的inode

    第二阶段将“hi”写入文件

    write 45:更新bitmap,文件系统首先会扫描bitmap来找到一个还没有使用的data block,未被使用的data block对应bit 0。找到之后,文件系统需要将该bit设置为1
    两次write 595 :文件系统挑选了data block 595,因为写入了两个字符,所以write 595被调用了两次
    write 33 : 更新文件x对应的inode中的size字段,第一个direct block number会更新

    第三阶段将“\n”换行符写入到文件

    和第二阶段类似,仔细阅读第二阶段。

    block cache代码

    • 首先在内存中,对于一个block只能有一份缓存。这是block cache必须维护的特性。
    • 其次,这里使用了与之前的spinlock略微不同的sleep lock。与spinlock不同的是,可以在I/O操作的过程中持有sleep lock。
    • 第三,它采用了LRU作为cache替换策略。
    • 第四,它有两层锁。第一层锁用来保护buffer cache的内部数据;第二层锁也就是sleep lock用来保护单个block的cache。
  • 相关阅读:
    Day55 web框架 入门 Django
    供应链全流程计划与排产解决方案核心功能概要
    DevOps&Apipost
    Python 用Ursina引擎制作一个3D迷宫游戏
    猿创征文 | 详解二叉树之遍历及其应用(动图遍历演示)
    在fastapi中实现异步
    谐云携手EMQ ,打造车联网平台联合解决方案
    [深入研究4G/5G/6G专题-45]: L3信令控制-1-软件功能和整体架构
    redis6.0源码分析:字典扩容与渐进式rehash
    Android 自动取色并设置沉浸式状态栏
  • 原文地址:https://blog.csdn.net/qq_43458555/article/details/134459099