第 6 章 - Azure RTOS FileX 容错模块

本章包含 Azure RTOS FileX 容错模块的说明,该模块设计用于在文件写入操作过程中介质断电或弹出时保持文件系统完整性。

FileX 容错模块概述

当应用程序将数据写入文件时,FileX 会同时更新数据群集和系统信息。 这些更新必须以原子操作的形式完成,以使文件系统中的信息保持一致。 例如,在将数据追加到文件时,FileX 需要在介质中查找可用群集,更新 FAT 链,更新目录条目中存档的长度,并可能会更新目录条目中的起始群集号。 电源故障或介质弹出可能会中断更新序列,这会使文件系统处于不一致状态。 如果未更正不一致状态,则更新的数据可能会丢失,并且由于系统信息损坏,后续文件系统操作可能会损坏介质上的其他文件或目录。

FileX 容错模块的工作方式是在将更新文件所需的步骤应用于文件系统之前,记录这些步骤。 如果文件更新成功,则会删除这些日志条目。 但是,如果文件更新遭到中断,日志条目会存储在介质上。 下次装载介质时,FileX 会从以前(未完成)的写入操作检测这些日志条目。 在这种情况下,FileX 可以回滚已对文件系统进行的更改,或是重新应用所需更改以完成以前的操作,从而从失败中恢复。 这样,如果介质在更新操作过程中断电,FileX 容错模块可保持文件系统完整性。

重要

FileX 容错模块并不是旨在防止由于包含有效数据的物理介质损坏而导致的文件系统损坏。

重要

FileX 容错模块保护媒体后,媒体不得由启用了容错的 FileX 外的其他任何内容装载。 这样做可能会导致文件系统中的日志条目与媒体上的系统信息不一致。 如果 FileX 容错模块在媒体被另一个文件系统更新后尝试处理日志条目,则恢复过程可能会失败,使整个文件系统处于不可预知的状态。

容错模块的使用

FileX 容错功能可用于 FileX 支持的所有 FAT 文件系统,包括 FAT12、FAT16、FAT32 和 exFAT。 若要启用容错功能,必须在定义了 FX_ENABLE_FAULT_TOLERANT 符号的情况下生成 FileX。 在运行时,应用程序会在调用 fx_media_open 之后立即调用 fx_fault_tolerant_enable,从而启动容错服务。 启用容错功能后,对指定介质进行的所有文件写入操作都会受到保护。 默认情况下,容错模块未启用。

重要

应用程序需要确保在调用 fx_fault_tolerant_enable 之前未访问文件系统。 如果在容错功能启用之前,应用程序将数据写入文件系统,则在以前的写入操作未完成时,写入操作可能会损坏介质,并且不会使用容错日志条目还原文件系统。

FileX 容错模块日志

FileX 容错日志在闪存中占用一个逻辑群集。 该群集的起始群集号索引记录在介质的引导扇区中,偏移通过符号 FX_FAULT_TOLERANT_BOOT_INDEX 进行指定。 默认情况下,此符号定义为 116。 此位置已选择,因为它在 FAT12/16/32 和 exFAT 规范中标记为保留。

图 5“日志结构布局”显示了日志结构的常规布局。 日志结构包含三个部分:日志标头、FAT 链和日志条目。

重要

日志条目中存储的所有多字节值都为 Little Endian 格式。

Log Structure Layout

图 5。 日志结构布局

日志标头区域包含描述整个日志结构并详细说明每个字段的信息。

表 8. 日志标头区域

字段 大小(以字节为单位) 说明
ID 4 标识 FileX 容错日志结构。 如果 ID 值不是 0x46544C52,则日志结构被视为无效。
总大小 2 指示整个日志结构的总大小(以字节为单位)。
标头校验和 2 用于转换日志标头区域的校验和。 如果标头字段未通过校验和验证,则日志结构被视为无效。
版本号 2 FileX 容错主要版本号和次要版本号。
保留 2 供将来扩展。

日志标头区域后跟 FAT 链日志区域。 图 9 包含描述应如何修改 FAT 链的信息。 此日志区域包含有关分配给文件的群集、从文件中删除的群集以及插入/删除位置的信息,并描述了 FAT 链日志区域中的每个字段。

表 9. FAT 链日志区域

字段 大小(以字节为单位) 说明
FAT 链日志校验和 2 整个 FAT 链日志区域的校验和。 如果未通过校验和验证,则 FAT 链日志区域被视为无效。
标志 1 有效标志值包括:
0x01 FAT 链有效
0x02 正在使用位图
保留 1 保留以供将来使用
插入点 – 前 4 新创建的链将附加到的群集(属于原始 FAT 链)。
新 FAT 链的头群集 4 新创建的 FAT 链的第一个群集
原始 FAT 链的头群集 4 要删除的原始 FAT 链部分的第一个群集。
插入点 – 后 4 新创建的 FAT 链联接的原始群集。
下一个删除点 4 此字段可帮助进行 FAT 链清理过程。

日志条目区域包含的日志条目描述从失败中恢复所需的更改。 FileX 容错模块中支持三种类型的日志条目:FAT 日志条目;目录日志条目;以及位图日志条目。

以下三个图和三个表详细描述了这些日志条目。

FAT Log Entry

图 6。 FAT 日志条目

表 10. FAT 日志条目

字段 大小(以字节为单位) 说明
类型 2 条目的类型,必须为 FX_FAULT_TOLERANT_FAT_LOG_TYPE
大小 2 此条目的大小
群集号 4 群集号
4 要写入 FAT 条目的值

Directory Log Entry

图 7。 目录日志条目

表 11. 目录日志条目

字段 大小(以字节为单位) 说明
类型 2 条目的类型,必须为 FX_FAULT_TOLERANT_DIRECTORY_LOG_TYPE
大小 2 此条目的大小
扇区偏移 4 到此目录所在的扇区的偏移(以字节为单位)。
日志扇区 4 目录条目所在的扇区
日志数据 变量 目录条目的内容

Bitmap Log Entry

图 8。 位图日志条目

表 12. 位图日志条目

字段 大小(以字节为单位) 说明
类型 2 条目的类型,必须为 FX_FAULT_TOLERANT_BITMAP_LOG_TYPE
大小 2 此条目的大小
群集号 4 群集号
4 要写入 FAT 条目的值

容错保护

FileX 容错模块启动后,它首先会在介质中搜索现有容错日志文件。 如果找不到有效日志文件,则 FileX 会将介质视为未受保护。 在这种情况下,FileX 会在介质上创建容错日志文件。

重要

*如果文件系统在 FileX 容错模块启动之前已损坏,则 FileX 无法保护该系统。 *

如果找到容错日志文件,则 FileX 会检查现有日志条目。 没有日志条目的日志文件指示以前的文件操作成功,所有日志条目都已删除。 在这种情况下,应用程序可以开始使用具有容错保护的文件系统。

不过,如果找到日志条目,则 FileX 需要完成以前的文件操作,或还原已应用于文件系统的更改,从而有效地撤消更改。 在任一情况下,将日志条目应用于文件系统后,文件系统会还原为一致状态,应用程序可以再次开始使用文件系统。

对于受 FileX 保护的介质,在文件更新操作过程中,数据部分会直接写入介质。 在 FileX 写入数据时,它还会记录需要应用于目录条目 FAT 表的所有更改。 此信息记录在文件容错日志条目中。 此方法可保证将数据写入介质后,对文件系统进行更新。 如果在数据写入阶段弹出介质,则至关重要的文件系统信息尚未更改。 因此,文件系统不受中断影响。

将所有数据成功写入介质后,FileX 随后会按照日志条目中的信息,将更改应用于系统信息(一次一个条目)。 所有系统信息都提交到介质后,日志条目会从容错日志中删除。 此时,FileX 便完成了文件更新操作。

在文件更新操作过程中,不会就地更新文件。 容错模块会为数据分配扇区以供写入新数据,然后删除包含要覆盖的数据的扇区,从而更新相关 FAT 条目以将新扇区链接到链中。 在需要修改群集中部分数据的情况下,FileX 会始终分配新群集,将包含更新的数据的旧群集中的所有数据写入新群集,然后释放旧群集。 这可保证如果文件更新中断,原始文件保持不变。 应用程序需要注意,在 FileX 容错保护下,更新文件中的数据需要介质具有足够的可用空间,以便在释放包含旧数据的扇区之前容纳新数据。 如果介质没有足够空间来容纳新数据,则更新操作会失败。