當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式硬件
[導(dǎo)讀]JFFS2 是一個(gè)開(kāi)放源碼的項(xiàng)目(www.infradead.org)。 它是在閃存上使用非常廣泛的讀/寫(xiě)文件系統(tǒng),在嵌入式系統(tǒng)中被普遍的應(yīng)用。這篇文章首先分析了在閃存上使用 JFFS2 的必要性,然后詳細(xì)的闡述了 JFFS2 實(shí)現(xiàn)的內(nèi)部機(jī)制,包括日志結(jié)構(gòu)的文件系統(tǒng),關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),掛載過(guò)程和垃圾收集機(jī)制。同時(shí)也指出了 JFFS2 的局限性,并介紹了最新的針對(duì) JFFS2 的不足進(jìn)行改進(jìn)的補(bǔ)丁程序。最后對(duì) JFFS3 的設(shè)計(jì)思想和現(xiàn)在的開(kāi)發(fā)狀況給予了簡(jiǎn)單的介紹。

JFFS2 是一個(gè)開(kāi)放源碼的項(xiàng)目(www.infradead.org)。 它是在閃存上使用非常廣泛的讀/寫(xiě)文件系統(tǒng),在嵌入式系統(tǒng)中被普遍的應(yīng)用。這篇文章首先分析了在閃存上使用 JFFS2 的必要性,然后詳細(xì)的闡述了 JFFS2 實(shí)現(xiàn)的內(nèi)部機(jī)制,包括日志結(jié)構(gòu)的文件系統(tǒng),關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),掛載過(guò)程和垃圾收集機(jī)制。同時(shí)也指出了 JFFS2 的局限性,并介紹了最新的針對(duì) JFFS2 的不足進(jìn)行改進(jìn)的補(bǔ)丁程序。最后對(duì) JFFS3 的設(shè)計(jì)思想和現(xiàn)在的開(kāi)發(fā)狀況給予了簡(jiǎn)單的介紹。

1. 為什么需要 JFFS2

這一小節(jié)首先介紹了閃存相對(duì)于磁盤(pán)介質(zhì)的特別之處,然后分析了將磁盤(pán)文件系統(tǒng)運(yùn)行在閃存上的不足,同時(shí)也給出了我們使用 JFFS2 的理由。

1.1 閃存(Flash Memory) 的特性和限制

這里所介紹的閃存的特性和限制都是從上層的文件系統(tǒng)的角度來(lái)看的,而不會(huì)涉及到具體的物理特性??偟膩?lái)說(shuō),有兩種類型的 flash memory: NOR flash 和 NAND flash. 先介紹一下這兩種閃存所具有的共同特性。

A) 閃存的最小尋址單位是字節(jié)(byte),而不是磁盤(pán)上的扇區(qū)(sector)。這意味著我們可以從一塊閃存的任意偏移(offset)讀數(shù)據(jù),但并不表明對(duì)閃存寫(xiě)操作也是以字節(jié)為單位進(jìn)行的。我們會(huì)在下面的闡述中找到答案。

B) 當(dāng)一塊閃存處在干凈的狀態(tài)時(shí)(被擦寫(xiě)過(guò),但是還沒(méi)有寫(xiě)操作發(fā)生),在這塊flash上的每一位(bit)都是邏輯1。

C) 閃存上的每一位(bit)可以被寫(xiě)操作置成邏輯0。 可是把邏輯 0 置成邏輯 1 卻不能按位(bit)來(lái)操作,而只能按擦寫(xiě)塊(erase block)為單位進(jìn)行擦寫(xiě)操作。擦寫(xiě)塊的大小從 4K 到128K 不等。從上層來(lái)看,擦寫(xiě)所完成的功能就是把擦寫(xiě)塊內(nèi)的每一位都重設(shè)置(reset)成邏輯 1。

D) 閃存的使用壽命是有限的。具體來(lái)說(shuō),閃存的使用壽命是由擦寫(xiě)塊的最大可擦寫(xiě)次數(shù)來(lái)決定的。超過(guò)了最大可擦寫(xiě)次數(shù),這個(gè)擦寫(xiě)塊就成為壞塊(bad block)了。因此為了避免某個(gè)擦寫(xiě)塊被過(guò)度擦寫(xiě),以至于它先于其他的擦寫(xiě)塊達(dá)到最大可擦寫(xiě)次數(shù),我們應(yīng)該在盡量小的影響性能的前提下,使擦寫(xiě)操作均勻的分布在每個(gè)擦寫(xiě)塊上。這個(gè)過(guò)程叫做磨損平衡(wear leveling)。

NOR flash 與 NAND flash 的不同之處:

A) NOR flash 讀/寫(xiě)操作的基本單位是字節(jié);而 NAND flash 又把擦寫(xiě)塊分成頁(yè)(page), 頁(yè)是寫(xiě)操作的基本單位,一般一個(gè)頁(yè)的大小是 512 或 2K 個(gè)字節(jié)。對(duì)于一個(gè)頁(yè)的重復(fù)寫(xiě)操作次數(shù)是有限制的,不同廠商生產(chǎn)的 NAND flash 有不同的限制,有些是一次,有些是四次,六次或十次。

B) 按照現(xiàn)在的技術(shù)水平,一般來(lái)說(shuō)NOR flash擦寫(xiě)塊的最大可擦寫(xiě)次數(shù)在十萬(wàn)次左右,NAND flash擦寫(xiě)塊的最大可擦寫(xiě)次數(shù)在百萬(wàn)次左右。

1.2 閃存轉(zhuǎn)換層

將磁盤(pán)文件系統(tǒng)(ext2, FAT)運(yùn)行在閃存上的很自然的方法就是在文件系統(tǒng)和閃存之間提供一個(gè)閃存轉(zhuǎn)換層(Flash Translation Layer), 它的功能就是將底層的閃存模擬成一個(gè)具有 512字節(jié)扇區(qū)大小的標(biāo)準(zhǔn)塊設(shè)備(block device)。對(duì)于文件系統(tǒng)來(lái)說(shuō),就像工作在一個(gè)普通的塊設(shè)備上一樣,沒(méi)有任何的差別。


圖一

一個(gè)閃存轉(zhuǎn)換層的最簡(jiǎn)單的實(shí)現(xiàn)就是將模擬的塊設(shè)備一對(duì)一的映射到閃存上。舉例來(lái)說(shuō),當(dāng)上層的文件系統(tǒng)要寫(xiě)一個(gè)塊設(shè)備的扇區(qū)時(shí),閃存轉(zhuǎn)換層要做下面的操作來(lái)完成這個(gè)寫(xiě)請(qǐng)求:

1 將這個(gè)扇區(qū)所在擦寫(xiě)塊地?cái)?shù)據(jù)讀到內(nèi)存中,放在緩存(buffer)中

2 將緩存中與這個(gè)扇區(qū)對(duì)應(yīng)的內(nèi)容用新的內(nèi)容替換掉

3 對(duì)該擦寫(xiě)塊執(zhí)行擦寫(xiě)操作

4 將緩沖中的數(shù)據(jù)寫(xiě)回該擦寫(xiě)塊

這種實(shí)現(xiàn)方式的缺點(diǎn)是很明顯的:

1 效率低,對(duì)一個(gè)扇區(qū)的更新要重寫(xiě)整個(gè)擦寫(xiě)塊上的數(shù)據(jù),造成數(shù)據(jù)帶寬很大的浪費(fèi)。

2 沒(méi)有提供磨損平衡,那些被頻繁更新的數(shù)據(jù)所在擦寫(xiě)塊將首先變成壞塊。

3 非常不安全,很容易引起數(shù)據(jù)的丟失。如果在上面的第三步和第四步之間發(fā)生了突然掉電(power loss),那么整個(gè)擦寫(xiě)塊中的數(shù)據(jù)就全部丟失了。這在突然掉電經(jīng)常發(fā)生的嵌入式系統(tǒng)中是不能接受的。

MTD 中的內(nèi)核模塊 mtdblock 就是基于這種機(jī)制實(shí)現(xiàn)的,同時(shí)還作了一些優(yōu)化。只有當(dāng)文件系統(tǒng)的寫(xiě)請(qǐng)求超過(guò)了一個(gè)擦寫(xiě)塊的邊界的時(shí)候,它才會(huì)執(zhí)行對(duì)閃存的擦寫(xiě),寫(xiě)回操作。

因此,為了解決上面這種實(shí)現(xiàn)方式的問(wèn)題,閃存轉(zhuǎn)換層需要做更多的事情。閃存轉(zhuǎn)換層不能只實(shí)現(xiàn)這種一對(duì)一的映射,而需要將模擬塊設(shè)備的扇區(qū)存儲(chǔ)在閃存的不同位置,并且維持扇區(qū)到閃存的映射關(guān)系。更進(jìn)一步,閃存轉(zhuǎn)換層還必須能理解上層文件系統(tǒng)的語(yǔ)義,否則閃存轉(zhuǎn)換層沒(méi)辦法做垃圾回收(Garbage Collection)。這樣實(shí)現(xiàn)最大的問(wèn)題就是效率不高,具體來(lái)說(shuō),閃存轉(zhuǎn)換層為了能理解上層文件系統(tǒng)的語(yǔ)義,必須對(duì)文件系統(tǒng)的每個(gè)寫(xiě)請(qǐng)求進(jìn)行解析,這勢(shì)必帶來(lái)寫(xiě)操作性能的下降。另外要求文件系統(tǒng)下面的一層去理解文件系統(tǒng)的語(yǔ)義,很顯然這不是最好的解決方式。我們還有很好的解決問(wèn)題的方法,就是實(shí)現(xiàn)一個(gè)特別針對(duì)閃存的文件系統(tǒng)。而 JFFS2 就是一個(gè)這樣的文件系統(tǒng)。

2. JFFS2

有 JFFS2 就要有 JFFS v1,沒(méi)錯(cuò),JFFS v1 最初是由瑞典的 Axis Communications AB 公司開(kāi)發(fā)的,使用在他們的嵌入式設(shè)備中,并且在 1999 年末基于 GNU GPL 發(fā)布出來(lái)。最初的發(fā)布版本基于 Linux 內(nèi)核 2.0,后來(lái) RedHat 將它移植到 Linux 內(nèi)核 2.2,做了大量的測(cè)試和 bug fix 的工作使它穩(wěn)定下來(lái),并且對(duì)簽約客戶提供商業(yè)支持。但是在使用的過(guò)程中,JFFS v1 設(shè)計(jì)中的局限被不斷的暴露出來(lái)。于是在 2001 年初的時(shí)候,RedHat 決定實(shí)現(xiàn)一個(gè)新的閃存文件系統(tǒng),這就是現(xiàn)在的 JFFS2。下面將詳細(xì)介紹 JFFS2 設(shè)計(jì)中主要的思想,關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)和垃圾收集機(jī)制。這將為我們實(shí)現(xiàn)一個(gè)閃存上的文件系統(tǒng)提供很好的啟示。首先,JFFS2 是一個(gè)日志結(jié)構(gòu)(log-structured)的文件系統(tǒng),包含數(shù)據(jù)和原數(shù)據(jù)(meta-data)的節(jié)點(diǎn)在閃存上順序的存儲(chǔ)。JFFS2 之所以選擇日志結(jié)構(gòu)的存儲(chǔ)方式,是因?yàn)閷?duì)閃存的更新應(yīng)該是 out-of-place 的更新方式,而不是對(duì)磁盤(pán)的 in-place 的更新方式。在閃存上 in-place 更新方式的問(wèn)題我們已經(jīng)在閃存轉(zhuǎn)換層一節(jié)描述過(guò)了。

2.1 節(jié)點(diǎn)頭部定義和兼容性

JFFS2 將文件系統(tǒng)的數(shù)據(jù)和原數(shù)據(jù)以節(jié)點(diǎn)的形式存儲(chǔ)在閃存上,具體來(lái)說(shuō)節(jié)點(diǎn)頭部的定義如下:


圖二

幻數(shù)屏蔽位:0x1985 用來(lái)標(biāo)識(shí) JFFS2 文件系統(tǒng)。

節(jié)點(diǎn)類型:JFFS2 自身定義了三種節(jié)點(diǎn)類型,但是考慮到文件系統(tǒng)可擴(kuò)展性和兼容性,JFFS2從 ext2 借鑒了經(jīng)驗(yàn),節(jié)點(diǎn)類型的最高兩位被用來(lái)定義節(jié)點(diǎn)的兼容屬性,具體來(lái)說(shuō)有下面幾種兼容屬性:

JFFS2_FEATURE_INCOMPAT:當(dāng) JFFS2 發(fā)現(xiàn)了一個(gè)不能識(shí)別的節(jié)點(diǎn)類型,并且它的兼容屬性是 JFFS2_FEATURE_INCOMPAT,那么 JFFS2 必須拒絕掛載(mount)文件系統(tǒng)。

JFFS2_FEATURE_ROCOMPAT:當(dāng) JFFS2 發(fā)現(xiàn)了一個(gè)不能識(shí)別的節(jié)點(diǎn)類型,并且它的兼容屬性是 JFFS2_FEATURE_ROCOMPAT,那么 JFFS2 必須以只讀的方式掛載文件系統(tǒng)。

JFFS2_FEATURE_RWCOMPAT_DELETE:當(dāng) JFFS2 發(fā)現(xiàn)了一個(gè)不能識(shí)別的節(jié)點(diǎn)類型,并且它的兼容屬性是 JFFS2_FEATURE_RWCOMPAT_DELETE,那么在垃圾回收的時(shí)候,這個(gè)節(jié)點(diǎn)可以被刪除。

JFFS2_FEATURE_RWCOMPAT_COPY:當(dāng) JFFS2 發(fā)現(xiàn)了一個(gè)不能識(shí)別的節(jié)點(diǎn)類型,并且它的兼容屬性是 JFFS2_FEATURE_RWCOMPAT_COPY,那么在垃圾回收的時(shí)候,這個(gè)節(jié)點(diǎn)要被拷貝到新的位置。

節(jié)點(diǎn)總長(zhǎng)度:包括節(jié)點(diǎn)頭和數(shù)據(jù)的長(zhǎng)度。

節(jié)點(diǎn)頭部 CRC 校驗(yàn):包含節(jié)點(diǎn)頭部的校驗(yàn)碼,為文件系統(tǒng)的可靠性提供了支持。

2.2 節(jié)點(diǎn)類型

JFFS2 定義了三種節(jié)點(diǎn)類型:

JFFS2_NODETYPE_INODE: INODE 節(jié)點(diǎn)包含了i-節(jié)點(diǎn)的原數(shù)據(jù)(i節(jié)點(diǎn)號(hào),文件的組 ID, 屬主 id, 訪問(wèn)時(shí)間,偏移,長(zhǎng)度等),文件數(shù)據(jù)被附在 INODE 節(jié)點(diǎn)之后。除此之外,每個(gè) INODE 節(jié)點(diǎn)還有一個(gè)版本號(hào),它被用來(lái)維護(hù)屬于一個(gè)i-節(jié)點(diǎn)的所有 INODE 節(jié)點(diǎn)的全序關(guān)系。下面舉例來(lái)說(shuō)明這個(gè)全序關(guān)系在 JFFS2 的使用:


圖三

因此,當(dāng)文件系統(tǒng)從閃存上讀節(jié)點(diǎn)信息后,會(huì)生成下面的映射信息:


圖四

根據(jù)這個(gè)映射信息表,文件系統(tǒng)就知道到相應(yīng)的 INODE 節(jié)點(diǎn)去讀取相應(yīng)的文件內(nèi)容。最后要說(shuō)明的是,JFFS2 支持文件數(shù)據(jù)的壓縮存儲(chǔ),因此在 INODE 節(jié)點(diǎn)中還包含了所使用的壓縮算法,在讀取數(shù)據(jù)的時(shí)候選擇相應(yīng)的壓縮算法來(lái)解壓縮。

JFFS2_NODETYPE_DIRENT:DIRENT 節(jié)點(diǎn)就是把文件名與 i 節(jié)點(diǎn)對(duì)應(yīng)起來(lái)。在 DIRENT節(jié)點(diǎn)中也有一個(gè)版本號(hào),這個(gè)版本號(hào)的作用主要是用來(lái)刪除一個(gè) dentry。具體來(lái)說(shuō),當(dāng)我們要從一個(gè)目錄中刪除一個(gè) dentry 時(shí),我們要寫(xiě)一個(gè) DIRENT 節(jié)點(diǎn),節(jié)點(diǎn)中的文件名與被刪除的 dentry 中的文件名相同,i 節(jié)點(diǎn)號(hào)置為 0,同時(shí)設(shè)置一個(gè)更高的版本號(hào)。

JFFS2_NODETYPE_CLEANMARKER:當(dāng)一個(gè)擦寫(xiě)塊被擦寫(xiě)完畢后,CLEANMARKER 節(jié)點(diǎn)會(huì)被寫(xiě)在 NOR flash 的開(kāi)頭,或 NAND flash 的 OOB(Out-Of-Band) 區(qū)域來(lái)表明這是一個(gè)干凈,可寫(xiě)的擦寫(xiě)塊。在 JFFS v1 中,如果掃描到開(kāi)頭的 1K 都是 0xFF 就認(rèn)為這個(gè)擦寫(xiě)塊是干凈的。但是在實(shí)際的測(cè)試中發(fā)現(xiàn),如果在擦寫(xiě)的過(guò)程中突然掉電,擦寫(xiě)塊上也可能會(huì)有大塊連續(xù) 0xFF,但是這并不表明這個(gè)擦寫(xiě)塊是干凈的。于是我們需要 CLEANMARKER 節(jié)點(diǎn)來(lái)確切的標(biāo)識(shí)一個(gè)干凈的擦寫(xiě)塊。

2.3 JFFS2節(jié)點(diǎn),擦寫(xiě)塊在內(nèi)存中的表示和操作

JFFS2 維護(hù)了幾個(gè)鏈表來(lái)管理擦寫(xiě)塊,根據(jù)擦寫(xiě)塊上的內(nèi)容,一個(gè)擦寫(xiě)塊會(huì)在不同的鏈表上。具體來(lái)說(shuō),當(dāng)一個(gè)擦寫(xiě)塊上都是合法(valid)的節(jié)點(diǎn)時(shí),它會(huì)在 clean_list 上;當(dāng)一個(gè)擦寫(xiě)塊包含至少一個(gè)過(guò)時(shí)(obsolete)的節(jié)點(diǎn)時(shí),它會(huì)在 dirty_list 上;當(dāng)一個(gè)擦寫(xiě)塊被擦寫(xiě)完畢,并被寫(xiě)入 CLEANMARKER 節(jié)點(diǎn)后,它會(huì)在 free_list 上。

通常情況下,JFFS2 順序的在擦寫(xiě)塊上寫(xiě)入不同的節(jié)點(diǎn),直到一個(gè)擦寫(xiě)塊被寫(xiě)滿。此時(shí) JFFS2 從 free_list 上取下一個(gè)擦寫(xiě)塊,繼續(xù)從擦寫(xiě)塊的開(kāi)頭開(kāi)始寫(xiě)入節(jié)點(diǎn)。當(dāng) free_list 上擦寫(xiě)塊的數(shù)量逐漸減少到一個(gè)預(yù)先設(shè)定的閥值的時(shí)候,垃圾回收就被觸發(fā)了,為文件系統(tǒng)清理出更多的可用擦寫(xiě)塊。為了減少對(duì)內(nèi)存的占用,JFFS2 并沒(méi)有把 i 節(jié)點(diǎn)所有的信息都保留在內(nèi)存中,而只是把那些在請(qǐng)求到來(lái)時(shí)不能很快獲得的信息保留在內(nèi)存中。具體來(lái)說(shuō),對(duì)于在閃存上的每個(gè) i 節(jié)點(diǎn),在內(nèi)存里都有一個(gè) struct jffs2_inode_cache 與之對(duì)應(yīng),這個(gè)結(jié)構(gòu)里保存了 i 節(jié)點(diǎn)號(hào),指向 i 節(jié)點(diǎn)的連接數(shù),以及一個(gè)指向?qū)儆谶@個(gè) i 節(jié)點(diǎn)的物理節(jié)點(diǎn)鏈表的指針。所有的 struct jffs2_inode_cache 存儲(chǔ)在一個(gè)哈希表中。閃存上的每個(gè)節(jié)點(diǎn)在內(nèi)存中由一個(gè) struct jffs2_raw_node_ref 表示,這個(gè)結(jié)構(gòu)里保存了此節(jié)點(diǎn)的物理偏移,總長(zhǎng)度,以及兩個(gè)指向 struct jffs2_raw_node_ref 的指針。一個(gè)指針指向此節(jié)點(diǎn)在物理擦寫(xiě)塊上的下一個(gè)節(jié)點(diǎn),另一個(gè)指針指向?qū)儆谕粋€(gè) i-節(jié)點(diǎn)的物理節(jié)點(diǎn)鏈表的下一個(gè)節(jié)點(diǎn)。


圖五

在閃存上的節(jié)點(diǎn)的起始偏移都是 4 字節(jié)對(duì)齊的,所以 struct jffs2_inode_cache 中flash_offset 的最低兩位沒(méi)有被用到。JFFS2 正好利用最低位作為此節(jié)點(diǎn)是否過(guò)時(shí)的標(biāo)記。

下面舉一例來(lái)說(shuō)明 JFFS2 是如何使用這些數(shù)據(jù)結(jié)構(gòu)的。VFS 調(diào)用 iget() 來(lái)得到一個(gè) i 節(jié)點(diǎn)的信息,當(dāng)這個(gè) i 節(jié)點(diǎn)不在緩存中的時(shí)候,VFS 就會(huì)調(diào)用 JFFS2 的 read_inode() 回調(diào)函數(shù)來(lái)得到 i 節(jié)點(diǎn)信息。傳給 read_inode() 的參數(shù)是 i 節(jié)點(diǎn)號(hào),JFFS2 用這個(gè) i 節(jié)點(diǎn)號(hào)從哈希表中查找相應(yīng)的 struct jffs2_inode_cache,然后利用屬于這個(gè) i 節(jié)點(diǎn)的節(jié)點(diǎn)鏈表從閃存上讀入節(jié)點(diǎn)信息,建立類似于表三的映射信息。

2.4 JFFS2 掛載過(guò)程

JFFS2 的掛載過(guò)程分為四個(gè)階段:

1) JFFS2 掃描閃存介質(zhì),檢查每個(gè)節(jié)點(diǎn) CRC 校驗(yàn)碼的合法性,同時(shí)分配了 struct jffs2_inode_cache 和 struct jffs2_raw_node_ref

2) 掃描每個(gè) i 節(jié)點(diǎn)的物理節(jié)點(diǎn)鏈表,標(biāo)識(shí)出過(guò)時(shí)的物理節(jié)點(diǎn);對(duì)每一個(gè)合法的 dentry 節(jié)點(diǎn),將相應(yīng)的 jffs2_inode_cache 中的 nlink 加一。

3 找出 nlink 為 0 的 jffs2_inode_cache,釋放相應(yīng)的節(jié)點(diǎn)。

4 釋放在掃描過(guò)程中使用的臨時(shí)信息。

2.5 JFFS2 垃圾回收機(jī)制

當(dāng) free_list 上的擦寫(xiě)塊數(shù)太少了,垃圾回收就會(huì)被觸發(fā)。垃圾回收主要的任務(wù)就是回收那些已經(jīng)過(guò)時(shí)的節(jié)點(diǎn),但是除此之外它還要考慮磨損平衡的問(wèn)題。因?yàn)槿绻晃兜膹?dirty_list上選取擦寫(xiě)塊進(jìn)行垃圾回收,那么 dirty_list 上的擦寫(xiě)塊將先于 clean_list 上的擦寫(xiě)塊被磨損壞。JFFS2 的處理方式是以 99% 的概率從 dirty_list,1% 的概率從 clean_list 上取一個(gè)擦寫(xiě)塊下來(lái)。由此可以看出 JFFS2 的設(shè)計(jì)思想是偏向于性能,同時(shí)兼顧磨損平衡。對(duì)這個(gè)塊上每一個(gè)沒(méi)有過(guò)時(shí)的節(jié)點(diǎn)執(zhí)行相同的操作:

1 找出這個(gè)節(jié)點(diǎn)所屬的 i 節(jié)點(diǎn)號(hào)(見(jiàn)圖五)。

2 調(diào)用 iget(),建立這個(gè) i 節(jié)點(diǎn)的文件映射表。

3 找出這個(gè)節(jié)點(diǎn)上沒(méi)有過(guò)時(shí)的數(shù)據(jù)內(nèi)容,并且如果合法的數(shù)據(jù)太少,JFFS2 還會(huì)合并相鄰的節(jié)點(diǎn)。

4 將數(shù)據(jù)讀入倒緩存里,然后將它拷貝到新的擦寫(xiě)塊上。

5 將回收的節(jié)點(diǎn)置為過(guò)時(shí)。

當(dāng)擦寫(xiě)塊上所有的節(jié)點(diǎn)都被置為過(guò)時(shí),就可以擦寫(xiě)這個(gè)擦寫(xiě)塊,回收使用它。

3. JFFS2 的不足之處

3.1 掛載時(shí)間過(guò)長(zhǎng)

JFFS2 的掛載過(guò)程需要對(duì)閃存從頭到尾的掃描,這個(gè)過(guò)程是很慢的,我們?cè)跍y(cè)試中發(fā)現(xiàn),掛載一個(gè) 16M 的閃存有時(shí)需要半分鐘以上的時(shí)間。

3.2 磨損平衡的隨意性(random nature)

JFFS2 對(duì)磨損平衡是用概率的方法來(lái)解決的,這很難保證磨損平衡的確定性。在某些情況下,可能造成對(duì)擦寫(xiě)塊不必要的擦寫(xiě)操作;在某些情況下,又會(huì)引起對(duì)磨損平衡調(diào)整的不及時(shí)。

3.3 很差的擴(kuò)展性

JFFS2 中有兩個(gè)地方的處理是 O(N) 的,這使得它的擴(kuò)展性很差。

首先,掛載時(shí)間同閃存的大小,閃存上節(jié)點(diǎn)數(shù)目成正比。

其次,雖然 JFFS2 盡可能的減少內(nèi)存的占用,但通過(guò)上面對(duì) JFFS2 的介紹我們可以知道實(shí)際上它對(duì)內(nèi)存的占用量是同 i 節(jié)點(diǎn)數(shù)和閃存上的節(jié)點(diǎn)數(shù)成正比的。

因此在實(shí)際應(yīng)用中,JFFS2 最大能用在 128M 的閃存上。

4. JFFS2 的新特性

最近加入到 JFFS2 中的兩個(gè)補(bǔ)丁程序分別解決了上面提到的掛載時(shí)間過(guò)長(zhǎng)和磨損平衡隨意性的問(wèn)題。

4.1 磨損塊小結(jié)補(bǔ)丁程序(erase block summary patch)

這個(gè)補(bǔ)丁程序最基本的思想就是用空間來(lái)?yè)Q時(shí)間。具體來(lái)說(shuō),就是將每個(gè)擦寫(xiě)塊每個(gè)節(jié)點(diǎn)的原數(shù)據(jù)信息寫(xiě)在這個(gè)擦寫(xiě)塊的最后,當(dāng) JFFS2 掛載的時(shí)候,對(duì)每個(gè)擦寫(xiě)塊只需要讀一次來(lái)讀取這個(gè)小結(jié)節(jié)點(diǎn),因此大大減少了掛載時(shí)間。使用了磨損塊小結(jié)補(bǔ)丁程序,一個(gè)擦寫(xiě)塊的結(jié)構(gòu)就像下面這樣:


圖六

根據(jù)我們的測(cè)試,使用磨損塊小結(jié)補(bǔ)丁程序,掛載一個(gè) 12M 的閃存需要 2~3 秒,掛載一個(gè) 16M 的閃存需要 3~4 秒。

4.2 改進(jìn)的磨損平衡補(bǔ)丁程序

這個(gè)補(bǔ)丁程序的基本思想是,記錄每個(gè)擦寫(xiě)塊的擦寫(xiě)次數(shù),當(dāng)閃存上各個(gè)擦寫(xiě)塊的擦寫(xiě)次數(shù)的差距超過(guò)某個(gè)預(yù)定的閥值,開(kāi)始進(jìn)行磨損平衡的調(diào)整。調(diào)整的策略是,在垃圾回收時(shí)將擦寫(xiě)次數(shù)小的擦寫(xiě)塊上的數(shù)據(jù)遷移到擦寫(xiě)次數(shù)大的擦寫(xiě)塊上。這樣一來(lái)我們提高了磨損平衡的確定性,我們可以知道什么時(shí)候開(kāi)始磨損平衡的調(diào)整,也可以知道選取哪些擦寫(xiě)塊進(jìn)行磨損平衡的調(diào)整。

4.3 擦寫(xiě)塊頭部補(bǔ)丁程序

在寫(xiě)改進(jìn)的磨損平衡補(bǔ)丁程序的過(guò)程之中,我們需要記錄每個(gè)擦寫(xiě)塊的擦寫(xiě)次數(shù),這個(gè)信息需要記錄在各自的擦寫(xiě)塊上??墒俏覀儼l(fā)現(xiàn) JFFS2 中缺少一種靈活的對(duì)每個(gè)擦寫(xiě)塊的信息進(jìn)行擴(kuò)展的機(jī)制。于是我們?yōu)槊總€(gè)擦寫(xiě)塊引入了擦寫(xiě)塊頭部(header),這個(gè)頭部負(fù)責(zé)紀(jì)錄每個(gè)擦寫(xiě)塊的信息(比如說(shuō)擦寫(xiě)次數(shù)),并且它提供了靈活的擴(kuò)展機(jī)制,將來(lái)如果有新的信息需要記錄,可以很容易的加入到頭部之中。

5. JFFS3 簡(jiǎn)介

雖然不斷有新的補(bǔ)丁程序來(lái)提高 JFFS2 的性能,但是不可擴(kuò)展性是它最大的問(wèn)題,但是這是它自身設(shè)計(jì)的先天缺陷,是沒(méi)有辦法靠后天來(lái)彌補(bǔ)的。因此我們需要一個(gè)全新的文件系統(tǒng),而 JFFS3 就是這樣的一個(gè)文件系統(tǒng),JFFS3 的設(shè)計(jì)目標(biāo)是支持大容量閃存(>1TB)的文件系統(tǒng)。JFFS3 與 JFFS2 在設(shè)計(jì)上根本的區(qū)別在于,JFFS3 將索引信息存放在閃存上,而 JFFS2將索引信息保存在內(nèi)存中。比如說(shuō),由給定的文件內(nèi)的偏移定位到存儲(chǔ)介質(zhì)上的物理偏移地址所需的信息,查找某個(gè)目錄下所有的目錄項(xiàng)所需的信息都是索引信息的一種。 JFFS3 現(xiàn)在還處于設(shè)計(jì)階段,文件系統(tǒng)的基本結(jié)構(gòu)借鑒了 Reiser4 的設(shè)計(jì)思想,整個(gè)文件系統(tǒng)就是一個(gè) B+ 樹(shù)。JFFS3 的發(fā)起者正工作于垃圾回收機(jī)制的設(shè)計(jì),這是 JFFS3 中最復(fù)雜,也是最富有挑戰(zhàn)性的部分。JFFS3 的設(shè)計(jì)文檔可以在http://www.linux-mtd.infradead.org/doc/jffs3.html 得到,有興趣的讀者可以積極參與到 JFFS3 的設(shè)計(jì)中,發(fā)表自己的見(jiàn)解,參與討論。


致謝

在這里要特別感謝David Woodhouse, Artem B. Bityutskiy,Joern 和 Thomas Gleixner,在參與到JFFS2的開(kāi)發(fā)過(guò)程中,這幾位主要的項(xiàng)目維護(hù)者(maintainer)不斷地給我?guī)椭托牡幕卮鹞业膯?wèn)題,在與他們的討論過(guò)程中碰撞出很多智慧的火花和富有啟發(fā)性的思想,尤其是他們對(duì)我的補(bǔ)丁程序提出的”尖刻”的問(wèn)題,讓我不斷的努力思考(thinking hard),不斷的完善它們。我想這種開(kāi)放,無(wú)私,客觀的精神正是開(kāi)源社區(qū)的精髓所在,吸引著越來(lái)越多的開(kāi)發(fā)者參與進(jìn)來(lái),并使開(kāi)源社區(qū)不斷的壯大。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉