UBIFS 是运行在ubi之上的文件系统,起源于jffs。实际上就是jffs3. 历史发展如下:
- jffs (journal flash file system)灵感来自于logfs。
- 随后出现了jffs2,有了不少改进
- a):只维护了在内存中的index树,而没有吧这个树存到flash中。
这个设计最初是非常好的,因为flash设备很小,那时候都是nor设备。
jffs2的设计大概只适合于小于32M的设备。在这种设备上,这个设计有很大的
好处:不需要更新index数据到flash上,读写速度快。而且不浪费flash有限
的存储空间。
但是随着nand flash的逐渐普及,flash设备的容量越来越大,导致这个设计
的弊端开始暴露:每一次mount都需要scan一遍flash用来建立index树。这会
导致mount的时间消耗完全无法忍受,而且最重要的是,这是一个O(n)的增长率。
与此同时,随着flash设备不断变大,jffs2需要维护的超级大的index树。导致
内存占用量很大,而且也是O(N)的增长率。
如上所述,我们可以说“jffs2 does not scale”.
- b):wear-leveling不是很好,导致flash设备很快会被损坏。
虽然在jffs2 wear-leveling还不错,但是事实证明可以更好。
- c): 没有提供断电保护机制
在jffs2中,如果发生断电,而且正在数据更新中,那只能表示corrupted了。
- d): 不支持write-back。
很显然,jffs3首先需要解决的问题必然是indexing的问题,但是这个问题不简单。
第一个想法就是将index树存到flash上面,没有错,这是必须的。但是这回引入一个严重
的问题。flash设备只能“out-place update”, 也就是说,不能直接覆盖flash上面的数据。flash
设备需要先进行erase操作,然后才可以进行write操作。那么,以前存放index树的区域,我们
不能直接更新。需要写到另外的地方,然后替换以前的内容。操作过程类似于COW。
一个node,写入新数据。更新parent node的指针指向新的node,那我就又要更新parent那么更严重的问题就来了,如果我需要跟新一棵树上面的一个node,那我需要新建
node。这样一直到整棵树的root。这是使用树结构存放数据而且使用COW的所有文件系统
都要忍受的一个痛。也就是说的wondering tree。如图
虽然很痛,但是这个问题还是解决了。当然,为了减少wandering tree的问题,我们还有很多方法,这个以后
再详细介绍。
两个部分,一个是log,一个是bud。 log存放事件,bud存放数据。当更新结束,提交完成,那log就会丢弃,还有一个重要的问题需要解决,那就是断电保护问题,所以在jffs3当中,引入了journal机制,包括
bud也会长成leaf。如果中间出现断电,那就按照log讲事件在提交一次。
ubi在mtd子系统中,做两件事情,坏块管理和wear-leveling。ubifs只需要集中精力做文件系统就行了。上文只是简单的介绍了一下jffs3的介绍,在实现过程中,为了可扩张性,讲jffs3分成了ubi和ubifs。
在接下来的一段时间,我会对ubifs进行进一步的解析,应该会包括那么几个部分:
1 磁盘结构:(SB,master,log,lpt,orphan,main)
2 IO 流程:(read write)
3 断电保护
4 GC 垃圾回收
5 空间预算
6 待定。。。