IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> UBIFS文件系统(四) -> 正文阅读

[开发测试]UBIFS文件系统(四)

UBIFS文件系统(四)

ubifs为异地更新,flash中的数据在变为脏之后并不会立即被清除,而是当文件系统通过make reservation已索引不到足够的存储空间时,才会触发GC(Garbage Collect)对空间进行整理和清除,该过程由ubifs_garbage_collect函数实现:检查文件系统的commit状态,若正处在后台commit则修改状态为立即commit状态,并返回错误,使其执行ubifs_run_commit过程。如果commit完成之后仍然索引不到足够的空间,则按如下顺序对脏LEB进行GC:

empty_list->freeable_list->dirty_heap->dirty_idx_heap->free heap->uncat->flash

其中,从empty_list和freeable_list中索引空间的前提是index leb预留充足,否则将直接从dirty_heap中开始索引空间。对于索引到的LEB,将置LPT标志为为taken,该LEB存在以下几种情况:

  1. dirty
    当该LEB为非index LEB,且dirty + free < leb_size时,需借助jhead[GCHD]的中转完成脏数据空间的回收,过程描述如下:
    LEB回收
  • 将LEB中有效node数据转移到jhead[GCHD]中,该过程会导致TNC、LPT的更新,node是否有效时根据该node是否存在于TNC中,即TNC中该node的key、inum和offs值是否和该node在flash中的各项值保持一致
  • 将除GCHD的其他jhead对应的wbuf同步到flash
  • 修改LEB的lpt,标识其可用空间为leb_size,若c->gc_lnum = -1,则令c->gc_lnum等于该释放的LEB number;否则,同步jhead[GCHD]->wbuf到flash中并unmap,返回LEB_FREED,此时将令c->gced_lnum为该dirty LEB的lnum,用于表示该LEB刚被GC回收。
    其中,将除GCHD之外的jhead->wbuf同步到flash的原因是:导致该LEB中的node成为脏数据的新node可能正存在于jhead->wbuf中,只有在将脏node删除之前将新的node数据同步到flash才不会导致数据的丢失。
  1. freeable
    处于freeable_list中的LEB肯定不是index LEB,当free == leb_size时直接unmap,当dirty > 0时,首先将除GCHD的其他jhead对应的wbuf同步到flash,修改lpt并unmap。若c->gc_lnum!=-1,返回LEB_FREED,否则返回LEB_RETAINED。

  2. index
    如果该LEB为index LEB,并不进行数据转移以及unmap操作,而是在TNC中将该LEB中的有效node置脏标志位,并将该LEB加入c->idx_gc链表中,清除该LEB对应lpt的index标志位,并且置该LEB的free空间为leb_size,返回LEB_FREED_IDX。此时该LEB在c->idx_gc链表中的unmap标志位为0,在unbifs_gc_start_commit中才会被置1,在ubifs_gc_end_commit中才会被真正的unmap。

其中,index LEB并不直接进行数据转移继而unmap的原因可能有二:jhead[GCHD]只包含有一个wbuf,而index node的data node不可能存在于同一个LEB中;index LEB只有在commit完成之后才能保证所有的index node同步到flash。如下图所示,当对index LEB中的node 3转移并回写到jhead[GCHD]中时,TNC中的node 3被更新为node 2,同时node 1至root的所有node被置脏,转移完成之后存储node 3的LEB被unmap,如果此时发生异常掉电,那么由于TNC中的其他index node还没有同步到flash(如node 1),则在开机进行replay时,将仍然按照未被更新的索引node建立TNC树,即node 1仍然指向node 3,而不是node 2,而此时由于node 3所在的LEB在此之前已经被unmap,将会导致索引错误从而使数据恢复失败。
在这里插入图片描述
在GC过程中判断c->gc_lnum的原因为:ubifs需要始终为GC额外保留一个LEB以保证有效数据的中转,当c->gc_lnum == -1时,表示此时没有额外的LEB供GC使用,所以本次GC产生的空闲LEB将被保留给GC使用,并返回LEB_RETAINED。而当c->gc_lnum != -1时,表示GC有预留的LEB以供使用,所以此次GC产生的空闲LEB可以作为他用,并返回LEB_FREED。当jhead[GCHD] ->wbuf写满时,总是通过seitch_gc_head函数将c->gc_lnum作为新的jhead[GCHD]->wbuf使用。在文件系统unmount时c->gc_lnum将被记录到master node中,但是当异常掉电而没有执行unmount时,master中的gc_lnum显示已经不是最新的值,此时则需要索引新的empty_leb作为gc_lnum(在函数ubifs_rcvry_gc_commit中实现)。

自上一次commit开始使用的journal LEB被加入到bud链表中,这些LEB都将被标记为taken,并且当LEB中有数据写入导致LPT更新时,会将该LEB归类到uncat中,当GC在寻找脏的LEB进行回收时,即便是处于uncat链表中,这些被标记为taken的LEB也不会被索引。这些LEB也不会成为freeable LEB,而是在commit开始时被GC,从而保证journal中的数据不会被破坏。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:56:28  更:2022-03-10 22:57:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:35:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码