2022年JFFS文件系统分析报告 .pdf
《2022年JFFS文件系统分析报告 .pdf》由会员分享,可在线阅读,更多相关《2022年JFFS文件系统分析报告 .pdf(13页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、JFFS2 文件系统分析报告本文在深入研究jffs2 源代码基础上,对JFFS2 文件系统的实现机制进行了分析,包括关键的数据结构及其之间的联系,文件系统的注册和挂载,以及其他主要的操作流程。1 JFFS2 层次结构在 Linux 系统中, JFFS2 文件系统处于虚拟文件系统层VFS 与存储技术设备层MTD 之间,如图 1 所示。 VFS 为内核中的各种文件系统提供一个统一的抽象层,并为上层用户提供具有统一格式的接口函数;MTD 子系统整合底层芯片驱动,为上层文件系统提供了统一访问 MTD 设备 (主要是 NOR 闪存和 NAND 闪存等设备 )的接口。 JFFS2 在内存中建立超级块信息
2、jffs2_sb_info 管理文件系统操作,建立索引节点信息jffs2_inode_info 管理打开的文件。VFS 层的超级块super_block和索引节点inode 分别包含JFFS2 文件系统的超级块信息jffs2_sb_info和索引节点信息jffs2_inode_info ,它们是JFFS2 和 VFS 间通信的主要接口。JFFS2 文件系统的超级块信息jffs2_sb_info 包含底层MTD 设备信息 mtd_info 指针,文件系统通过该指针访问MTD 设备,实现JFFS2 和底层 MTD 设备驱动之间的通信。应用层VFS层JFFS2文件系统层NOR 闪存, NAND 闪存
3、驱动层super_blockinodejffs2_sb_infojffs2_inode_infomtd_infoMTD 层图 1 JFFS2 文件系统层次2 JFFS2 数据实体JFFS2 在 Flash 上只存储两种类型的数据实体,分别为jffs2_raw_inode 和 jffs2_raw_ dirent。jffs2_raw_dirent :包括文件名、 ino 号、父节点ino 号、版本号、校验码等信息,它用来形成整个文件系统的层次目录结构。jffs2_raw_inode :包括文件ino 号、版本号、访问权限、修改时间、本节点所包含的数名师资料总结 - - -精品资料欢迎下载 - -
4、- - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 13 页 - - - - - - - - - 据文件中的起始位置及本节点所包含的数据大小等信息,它用来管理文件的所有数据。一个目录文件由多个jffs2_raw_dirent组成。而普通文件,符号链接文件,设备文件,FIFO 文件等都由一个或多个jffs2_raw_inode 数据实体组成。图2 表示了一个Flash 中数据实体的逻辑分布,物理上所有的数据实体是离散分布的,其位置由写入时Flash 空闲空间位置决定的。rdrdriririnamenamedatadata,一个
5、目录项一个文件4字节对齐rd:jffs2_raw_direntri:jffs2_raw_inode图 2 Flash 空间上的数据实体JFFS2 文件系统在挂载时扫描整个Flash,每个 jffs2_raw_inode 数据实体都会记录其所属的文件的inode 号及其他元数据, 以及数据实体中存储的数据的长度及在文件内部的偏移。而 jffs2_raw_dirent数据实体中存有目录项对应的文件的inode 号及目录项所在的目录的inode 号等信息。 JFFS2 在扫描时根据jffs2_raw_dirent 数据实体中的信息在内存中建立文件系统的目录树信息,类似的, 根据 jffs2_raw_
6、inode 数据实体中的信息建立起文件数据的寻址信息。 为了提高文件数据的寻址效率,JFFS2 将属于同一个文件的jffs2_raw_inode 数据实体组织为一颗红黑树, 在挂载扫描过程中检测到的每一个有效的jffs2_raw_inode 都会被添加到所属文件的红黑树。在文件数据被更新的情况下,被更新的旧数据所在的jffs2_raw_inode数 据 实 体 会 被 标 记 为 无 效 ,同 时 从 文 件 的 红 黑 树中 删 除 。 然 后 将 新的 数 据 组 织 为jffs2_raw_inode 数据实体写入Flash 并将新的数据实体加入红黑树。3 JFFS2 逻辑结构与磁盘文件系
7、统不同,JFFS2 文件系统不在Flash 设备上存储文件系统结构信息,所有的信息都分散在各个数据实体节点之中,在系统初始化的时候,扫描整个Flash 设备,从中建立起文件系统在内存中的映像,系统在运行期间,就利用这些内存中的信息进行各种文件操作。JFFS2 为每一个 Flash 设备维护一个超级块结构jffs2_sb_info , 这个结构含有整个Flash设备的信息。 通过这个数据结构,系统维护了几个重要的链表,这几个链表构成了整个文件系统的骨架。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - -
8、- - - 第 2 页,共 13 页 - - - - - - - - - 3.1 擦除块信息链表在 jffs2_sb_info 中维护着多个擦除块链表,如表1 所示,链表中每一个节点包含一个擦除块。表1 擦除块信息链表链表链表中擦除块的性质clean_list 只包含有效数据结点very_dirty_list 所含数据结点大部分都已过时dirty_list 至少含有一个过时数据结点erasable_list 所有的数据结点都过时需要擦除。但尚未“ 调度 ” 到erase_pending_list erasable_pending_wbuf_list 同erase_pending_list,但擦
9、除必须等待wbuf 冲刷后erasing_list 当前正在擦除erase_pending_list 当前正等待擦除erase_complete_list 擦除已完成,但尚未写入CLEANMARKER free_list 擦除完成,且已经写入CLEANMARKER bad_list 含有损坏单元bad_used_list 含有损坏单元,但含有数据擦除块由 jffs2_eraseblock 数据结构表示, 该结构包含该擦除块在Flash 设备的偏移位置、该块的空间使用情况,以及所有存在于该擦除块的数据实体的链表等信息。通过这些擦除块链表,我们可以找到存在于Flash 设备上的任何一个擦除块,及其
10、上面的数据实体,如图3所示。jffs2_sb_infojffs2_eraseblocknextprevjffs2_eraseblocknextprevjffs2_eraseblocknextprevfirst_nodelast_nodefirst_nodelast_nodefirst_nodelast_nodejffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inonextprevfree_list图 3 擦除链表的示意图3.2 incache_list链表在 jffs2_sb
11、_info 中, 系统维护着一个inocache_list 链表,链表中每个元素jffs2_inode_cache代表一个文件,包括普通文件和目录文件,由唯一的ino 号所标识。所有属于同一个文件的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 13 页 - - - - - - - - - 节点信息jffs2_raw_node_ref 由指针形成链表,由 jffs2_inode_cache 的 notes 域指向, 这样对文件任何一个节点操作都可以通过这个链表定位,如图4
12、 所示。jffs2_sb_infoinocache_list jffs2_inode_cacheHash table根据文件的 ino号确定nextnotesNULLjffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inonextnotesnextnotes jffs2_inode_cache jffs2_inode_cachenullnullnull图 4 inocache_list 链表3.3 jffs2_inode_info链表jffs2_inode_info是在打开文件
13、时创建的,jffs2中通过jffs2_inode_info的 fragtree 、metedata 或者dents 来组织打开文件的所有数据实体的内核描述符。普通文件包含若干jffs2_raw_inode数 据 实 体 , 它 们 的 内 核 描 述 符jffs2_raw_node_ref组 成 的 链 表 由jffs2_inode_cache 的 nodes 指向 (前面我们已经叙述)。如果是目录文件,则在打开文件时为数据实体的内核描述符jffs2_raw_node_ref 创建相应的 jffs2_full_dirent , 并组织为链表由dents指向。jffs2_inode_infofr
14、agtreemetedatadentsinocachejffs2_raw_node_refnext_in_inonextnotes jffs2_inode_cachenullinocache_listrawnext versioninonhashtypename jffs2_full_direntrawnext versioninonhashtypename jffs2_full_direntjffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inoNULLflash_offsetflash_offsetflash_offset_tot
15、len_totlen_totlenjffs2_full_dnoderawofs sizefrags名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 13 页 - - - - - - - - - 图 5 目录文件打开时的jffs2_inode_info 链表如果是普通文件, 在打开文件时创建相应的jffs2_full_dnode 和 jffs2_node_frag 数据结构, 并由后者组织在由fragtree 指向的红黑树中。对于目录文件、符号链接和设备文件只有一个jffs2
16、_raw_inode数 据 实 体 所 以 没 有 必 要 使 用 红 黑 树 则 由metadata 直 接 指 向 它 们 的jffs2_full_dnode 。图 6 展示了一个普通文件打开时的jffs2_inode_info 链表。jffs2_inode_infofragtreemetedatadentsinocachejffs2_node_fragrb_rightrb_leftrbnoderb_rightrb_leftrbnodejffs2_node_fragrb_rightrb_leftrbnode,jffs2_full_dnoderawofs sizefragsjffs2_ful
17、l_dnoderawofs sizefragsjffs2_full_dnoderawofs sizefragsjffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inojffs2_raw_node_refnext_in_inonextnotes jffs2_inode_cachenullinocache_list图 6 普通文件打开时的jffs2_inode_info 链表4 JFFS2 文件系统注册在配置内核时选择对jffs2 的支持,那么jffs2 的源代码编译后被静态链接入内核映象,在初始化期间init 内核线程执行init_jf
18、fs2_fs函数完成jffs2 的注册, init_jffs2_fs 函数主要完成以下工作:检测基本数据结构jffs2_unknown_node 、jffs2_raw_dirent 、jffs2_raw_inode 等的大小的合法性 ; 调 用jffs2_compressors_init()函 数 分 配 解 压 缩 所 需 空 间deflate_workspace和名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 13 页 - - - - - - - - - inflat
19、e_workspace; 调用 jffs2_create_slab_caches()为数据实体jffs2_raw_dirent 和 jffs2_raw_inode 、数据实体内核描述符jffs2_raw_node_ref 、文件的内核描述符jffs2_inode_cache 、jffs2_full_dnode和 jffs2_node_frag 等数据结构通过kmem_cache_create函数创建相应的内存高速缓存调用register_filesystem函数向系统注册JFFS2 文件系统,所有已注册文件系统的file_system_type 组成一个链表,由内核全局变量file_syste
20、ms 指向。其中在 jffs2 源代码文件中定义了file_system_type 类型的变量jffs2_fs_type ,其名字为“ jffs2”,而 “ get_sb” 方法为 “ jffs2_get_sb ” ,它是具体文件系统所提供的各种方法的总入口。static s truc t file_sys tem _t ype jf fs 2_fs _t yp e = .owner =THI S_ MODULE,.nam e =jf fs 2,.get_sb =jffs 2_get_sb,.kill_sb =jffs 2_kill_sb,;5 JFFS2 文件系统挂载在挂载文件系统时内核为之
21、创建VFS 的 super_block 数据结构,以及根目录的inode、dentry 等数据结构。挂载根文件系统时函数调用链如下:m ount_root-m ount_block_root-do_mount_root-s ys _m ount -do_mount-do_new_mount-do_kern_m oun t- vfs _kern_mount- t ype- get_sb= jf fs 2_get_sbjffs2_get_sb 在初始化VFS 超级块对象时为flash 上所有的数据实体和文件建立内核描述符。 内核描述符是数据实体和文件的“ 地图 ” ,由于在 flash 中缺少对文
22、件数据的索引机制,所以早在挂载文件系统时就必须建立文件及其数据实体的映射关系。jffs2_get_sb 主要工作:设置文件系统方法表的指针jffs2_sb_info-s_op = &jffs2_super_operations; ,它提供了访问整个文件系统的基本方法。设置 jffs2_sb_info-mtd指向在初始化Flash 设备驱动程序时创建的mtd_info 数据结构,它物理上描述了整个Flash 板块并提供了访问Flash 的底层驱动程序。从后文可见, jffs2名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心
23、整理 - - - - - - - 第 6 页,共 13 页 - - - - - - - - - 方法最终通过调用flash 驱动程序中将数据实体jffs2_raw_dirent或 jffs2_raw_inode 及后继数据块写入flash(或从中读出) 。真正初始化VFS 超级块 super_block 数据结构、 为 flash 上所有数据实体建立内核描述符jffs2_raw_node_ref 、 为 所 有 文 件 创 建 内 核 描 述 符jffs2_inode_cache的 任 务 交 给jffs2_do_fill_super函数完成。jffs2_do_fill_super 函数主要工
24、作:根据 mtd_info 数据结构的相应域来设置jffs2_sb_info 中与 flash 参数有关的域:擦除块大小和分区大小。 jffs2 驱动在成功擦除了一个擦除块后,要写入类型为CLEANMARKER的数据实体来标记擦除成功完成。分配 c-wbuf , c-inocache_list 缓冲区, 调用 jffs2_do_mount_fs() 函数完成挂载jffs2 文件系统的绝大部分工作。为根目录 “/ ”创建 VFS 的 inode 和 dentry,除根目录外任何文件的inode 和 dentry 等数据结构都是等到打开文件时才创建。文件系统超级块super_block 的 s_r
25、oot 指针指向根目录的 dentry,而 dentry 的 d_inode 指向其 inode,而 inode 的 i_sb 又指向文件系统超级块super_block。 创建 inode的工作由 iget内联函数完成。 iget函数的函数调用路径为:iget- sb-s_op-read_inode=jffs2_read_inode 挂载文件系统的最后还要设置jffs2_sb_info中的几个域,比如页缓冲区中的页面大小s_blocksize, 标识文件系统的“ 魔数 ”s_magic 。另外,就是要启动GC (Garbage Collecting,垃圾回收)内核线程了。jffs2 日志文件
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年JFFS文件系统分析报告 2022 JFFS 文件系统 分析 报告
限制150内