ubifs design

Flash memory在存储之前需要擦除,所以flash mem文件系统需要做异地更新。

Flash memory的擦除过程比较耗时,选择异地更新会比较明智,往一个已经擦除好的block上写

比拿到脏块擦除后再写要快得多。

要做异地更新,那自然有做擦除脏数据块的机制,即垃圾收集机制。写数据只需要往擦除过的block写,

GC则需要回收丢弃的block并擦除之。

文件系统需要能够标识存储在erase block上的数据,让GC机制工作。FS是用过文件名来找到所属文件的数据,

而GC则是通过data找到是否属于某个文件。

文件的metadata和data保存在一起,称之为node,每一个node记录了所属文件,以及什么数据保存在该node中

在这一点上,jffs2与ubifs相同,都是基于node设计。在读取eraseblock的数据时可以直接决定是否搬运到其他EB上,亦或丢弃。

jffs2与ubifs最大的不同之处在于,ubifs把文件index存储在Flash上,而jffs2则把index建立在内存中。

这会导致jffs2支持的尺寸有限制,mount时间与内存消耗都会随flash mem size正比增长。

存储index到flash中非常麻烦,index也需要做异地更新,引用index的index也需要更新。解决这种依赖更新的办法是使用Wandering tree。

ubifs的游离树是使用B+树,树的叶子节点保存文件信息,其他节点为index nodes。

对叶子节点的更新,会引起父节点的更新,知道根节点,更新的inex nodes的数目显然等于树的高度。

树的根节点需要存在固定的位置,即masternode中,会有两个LEB(ubifs使用的逻辑擦除块)LEB1/LEB2中各保存一份。

使用两个LEB保存两份master node是为了出现损坏时以便恢复。有两种情况会导致master node损坏,1,写master node时断电,

2,flash介质本身出现损坏。第一种情况可以使用前一版本的master node来恢复,而第二种情况则无法判断哪个是有效的master node。

第二种情况比较麻烦,需要readback数据来重建或找到问题所在。

UBIFS在创建的时候有6个areas是固定的,

UBI device上的第一个LEB是LEB0,保存superblock node,保存文件系统基本不变的参数。

Master node存在LEB1,LEB2,

LOG area,

LEB properties tree aera

orphan area

main area

superblock与mater node前面都有提到了。

LOG是UBIFS日志的一部分,用来降低falsh index更新频率。

更新文件系统的叶子节点,需要地递归更新其父节点,可能会频繁的做这样的动作,以至效率低下。

UBIFS通过日志,仅仅写叶子节点,并不立即更新flash上的index,当然内存中的index会立即更新,当日志系统认为日志满了,进行提交。

提交过程包括写入memory index以及相应的master node。

日志的数据总是比falsh的index相比更新,在mount的时候会replay日志中的index。

日志的size是在mkfs.ubifs确定,缺省情况下,ubifs不使用fask unmount,在unmount前执行一次commit。

这会让日志几乎为空,下次mount会非常快。

commit过程本身不会从日志中移动叶子节点,而是修改日志本身,即修改日志的位置。

log中包含两类节点,commit start node记录一个commit一斤刚开始,reference nodes记录组成journal的LEBs的序号。

这些LEBs叫做buds,日志包含log和buds,log的尺寸是固定的,可认为是一个circular buffer。


待续。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值