1概述
Littlefs是arm公司设计的文件系统,其核心设计主要是掉电安全,在掉电安全的基础上,littlefs对资源开销、读写性能也进行了部分优化。本篇文章,主要讲述littlefs的掉电安全实现,并且不涉及到具体的代码逻辑,其他优化的讲解在其他文章中说明。
2掉电安全
2.1元数据类型
littlefs的数据类型有两种:真实的数据以及元数据,其中真实的数据是用户真正需要读写的数据,它的载体是文件,并且每个文件都会选择一个或者多个物理block来存储真实的数据,两个不同文件的数据不会同时存储到同一个物理block。元数据包括了目录的信息,以及部分用户不可见的信息(如创建,删除等日志信息),它的载体是目录,并且每个目录都会选择一个或者多个物理block来存储对当前目录的任意操作日志和管理数据,两个不同目录的元数据不会同时存储到同一个物理block。
元数据的格式为:
元数据分为三个部分的内容,tag标识数据类型,说明本次操作的是目录,还是文件,是创建操作,还是删除擦嘴,data是具体的内容,如果是目录,则data的内容是目录所在的block编号,如果是文件,则data的内容为文件的首地址所在的block编号以及文件的大小。
描述文件信息的元数据为:
Littlefs简化了文件的元数据信息,只需要文件的首地址块和文件大小,至于文件会占用哪些块,这个是文件自己通过ctz链表链接起来管理的。
描述目录信息的元数据为:
同样,littlefs也简化了目录的元数据信息,创建一个目录后,父目录只需要知道目录所占据的首个块是哪个,至于目录会占用哪些块,这个是目录通过dir链表链接起来管理的。
2.2 场景分析
一个简单的拓扑结构为(三个目录,一个文件):
如图所示的场景,一个目录对应了一个物理块,元数据块A对应的是目录A,目录A是目录C和目录B的父目录,文件A对应了两个块,常规数据块A和常规数据块B,常规数据块A中存在管理信息指向常规数据块B。
下面通过三个场景,来分析littlefs的掉电安全特性。
2.2.1写文件
写文件的过程为:
(1)待写入
(2)写常规数据
(3)写元数据
主要分为两个阶段:写实际数据、写元数据,我们在这里模拟一下异常掉电的情况:
(1)写实际数据的时候掉电
写实际数据会先申请一个新的块,把对应的数据先更新到这个块上,并更新索引信息,指向下一个块。此时,掉电了,由于元数据没有更新,这个新的块不会被文件系统检索到,新写入的数据会丢失,但是旧数据和文件系统都是稳定的。
(2)写元数据的时候掉电
元数据通过CRC保护起来了,每提交一次修改,都会用crc进行校验,校验不通过的元数据,被认为是无用的数据。同一个文件的元数据随着写入次数的增加会有多份,但是只有最新写入的数据是有效的,在文件系统检索的时候,会剔除掉重复的元数据。此时,掉电了,新的元数据由于crc校验不过,所以,旧的元数据会生效,新写入的数据会丢失,但是旧数据和文件系统都是稳定的。
2.2.2删除文件
按照常规的理解,删除目录的过程,和写数据的过程类似,只需要提交对应的元数据到文件所在目录块即可,但是littlefs设计了一套dir list,将所有的目录所在的块串联成一个单链表,用于快速的遍历整个文件系统,所以,真实的拓扑结构为:
在删除目录的时候,需要在父目录提交删除的管理信息,还需要在dir list的上游目录提交list修改的信息,共涉及到往两个目录块提交管理信息。具体的过程为:
(1)删目录
(2)修改dir list
模拟一下异常掉电的过程:
(1)父目录提交删除的管理信息时掉电
由于crc校验不通过,认为本次提交是无效的。
(2)父目录提交删除的管理信息后,往dir list的上游目录提交list修改的信息时掉电
在往父目录提交删除的管理信息时,提交了一个特殊的tag,叫movestate tag,标识着开始删除文件了,在往dir list的上游目录提交list修改的信息,也会提交一次movestate tag,标识着删除文件结束了。当文件系统mount的时候,会检查是否存在movestate异或不为0的情况,如果不为0,说明发生了开始,但是没有结束的操作,文件系统则可以继续没有完成的操作,往dir list的上游目录继续提交list修改的信息。所以,父目录提交删除的管理信息后,往dir list的上游目录提交list修改的信息时掉电,由于movestate异或不为0,文件系统重新mount后会继续删除操作。
2.2.3移动文件
移动文件需要在源目录块提交删除的管理信息,在目的目录块提交创建的管理信息,也涉及到了往两个目录块提交管理信息。具体的过程为:
(1)待移动
(2)删除
(3)创建
移动目录的过程,和移动文件的过程是一致的,不会引起dir list的变动。
模拟一下异常掉电的过程:
(1)源目录块提交删除的管理信息时掉电
由于crc校验不通过,认为本次提交是无效的。
(2)源目录提交删除的管理信息后,在目的目录块提交创建的管理信息时掉电
在往源目录提交删除的管理信息时,提交了一个特殊的tag,叫movestate tag,标识着开始移动文件了,在往目的目录块提交创建的管理信息,也会提交一次movestate tag,标识着移动文件结束了。当文件系统mount的时候,会检查是否存在movestate异或不为0的情况,如果不为0,说明发生了开始,但是没有结束的操作,文件系统则可以继续没有完成的操作,往目的目录块提交创建的管理信息。所以,源目录提交删除的管理信息后,在目的目录块提交创建的管理信息时掉电,由于movestate异或不为0,文件系统重新mount后会继续移动操作。
版权归原作者 笑ba 所有, 如有侵权,请联系我们删除。