LittleFs文件系統(tǒng)

0 簡介

LittleFs設計之初的重點特性是:
(1)低資源消耗铅辞;
(2)掉電保護厌漂;
(3)擦寫均衡,
本章節(jié)重點討論第(2)和(3)這兩個特性斟珊,第(1)個特性則貫穿在整個設計過程中苇倡。后文把LittleFs簡稱為lfs。

1 具體功能介紹

1.1 掉電保護

最經典的掉電保護方法有兩種囤踩,一種是使用日志旨椒,一種是通過COW方式。lfs結合了兩種方法堵漱,并優(yōu)化了兩種方案的缺點综慎,提供了一套掉電保護策略。

1.1.1 日志方式


具體步驟為:
(1) 寫入數(shù)據(jù)之前勤庐,先在日志區(qū)存儲開始標志示惊,記錄要寫入的數(shù)據(jù)位置和大小愉镰;
(2) 待寫入的數(shù)據(jù)寫入日志區(qū)米罚;
(3) 待寫入的數(shù)據(jù)寫入數(shù)據(jù)區(qū);
(4) 寫入完成之后岛杀,在日志區(qū)記錄結束標志。
模擬掉電場景:
(1) 步驟1完成崭孤,步驟2沒有完成类嗤;重啟之后,保持原來的數(shù)據(jù)辨宠,日志無效遗锣;
(2) 步驟1,2完成了嗤形,步驟3沒有完成精偿,嘗試把步驟2的數(shù)據(jù)寫入到數(shù)據(jù)區(qū);
(3) 步驟1,2,3完成了赋兵,步驟4沒有完成笔咽,同樣嘗試把步驟2的數(shù)據(jù)寫入到數(shù)據(jù)區(qū);

1.1.2 Cow機制


具體步驟為:
(1) 想更新節(jié)點F的數(shù)據(jù)霹期,先申請一個新的節(jié)點叶组,把F的舊數(shù)據(jù)拷貝過去,然后更新新的數(shù)據(jù)历造;
(2) 把父節(jié)點的指針指向新的節(jié)點甩十,去掉舊節(jié)點的指針船庇。
模擬掉電場景:
(1)步驟(1)完成了,步驟(2)沒有完成侣监,則使用舊的數(shù)據(jù)鸭轮,新的節(jié)點變成孤兒節(jié)點。

1.1.3 lfs掉電保護

lfs結合了日志方式和COW機制兩種方式進行掉電保護橄霉,并且優(yōu)化了兩種方案窃爷。
前面談過文件系統(tǒng)三要素,超級塊酪劫,inode吞鸭,以及數(shù)據(jù)。對應lfs來說覆糟,他把超級塊以及inode通過日志的方式存儲刻剥,兩種采用統(tǒng)一的存儲結構,后文稱兩者為元數(shù)據(jù)滩字;普通數(shù)據(jù)則采用cow的方式存儲造虏,采用czt逆序鏈表的方式。


1.1.3.1 元數(shù)據(jù)的存儲


元數(shù)據(jù)(對應root麦箍,dir)采用雙block的方式存儲漓藕,互為備份,每個block都有一個revision序號挟裂,值越大享钞,表示block的數(shù)據(jù)越新,每個block默認可以存儲最多0xff個文件的數(shù)據(jù)诀蓉,如果超過這個值栗竖,則需要compact(壓縮)。
Compact是干什么呢渠啤? 即當數(shù)據(jù)的大小大于某個值的時候狐肢,把數(shù)據(jù)整合,剔除同一個id的舊的數(shù)據(jù)沥曹,然后寫入到備份block里面份名。
在compact的過程中,如果發(fā)現(xiàn)整合的數(shù)據(jù)還是大于某個值妓美,怎么辦呢僵腺?需要split(分片)。

1.1.3.2 普通數(shù)據(jù)的存儲(CTZ)

Lfs的數(shù)據(jù)采用ctz鏈表的方式逆向管理壶栋,這與傳統(tǒng)的文件系統(tǒng)有比較大的差別想邦。具體對比見下圖所示。



傳統(tǒng)的方式添加數(shù)據(jù)委刘,需要建立舊的數(shù)據(jù)到新的數(shù)據(jù)的索引丧没。這樣做有兩個弊端:
(1) 當數(shù)據(jù)特別多的時候鹰椒,這樣一個個的索引過去查找,比較費時間呕童。
(2) 當使用cow機制的時候漆际,在文件后面每增加一次數(shù)據(jù),需要把所有的索引都重新建立一個夺饲,這樣帶來的性能損耗特別大奸汇。
為了解決這兩個問題,lfs采用了下面的管理方式往声。



(1) 采用逆向的指針擂找,這樣常規(guī)的追加數(shù)據(jù),不需要額外的開銷來重新建立所有的索引浩销;
(2) 每個偶數(shù)block有多個指針贯涎,指向更遠的數(shù)據(jù),這樣可以在檢索的時候加快速度慢洋。

指針的建立采用了CTZ(二進制中最后一個不為0的位塘雳,其右邊0的個數(shù))的方式。大概原理就是普筹,block N 如果是一個能被 2^X整除的數(shù)败明,那么他就存在指向N – 2^X的指針,指針的數(shù)目為ctz(N)+1太防。



從上表可以看出妻顶,block 2多一個指向0的指針,block 4多一個指向0,2的指針蜒车。
咱們已經知道了實際數(shù)據(jù)(對應file)采用czt list的方式存儲讳嘱,最新的數(shù)據(jù)block指向次新的數(shù)據(jù)block(這個是為了提高COW的效率)。
一次常規(guī)更新數(shù)據(jù)的過程大概為(實際比這個復雜很多醇王,需要考慮cache呢燥、孤兒崭添、crc等問題):
(1) 往file文件中寫入數(shù)據(jù)寓娩;
(2) 申請一個新的block,并且把file文件最后一個block的數(shù)據(jù)復制到新的block呼渣,并追加要寫入的數(shù)據(jù)棘伴;
(3) 更新新block的czt list(在block的頭部會占用一定的4字節(jié)倍數(shù)的字節(jié)來記錄索引,這個czt list只是用來fseek的加快速度)屁置;
(4) 文件fclose的時候焊夸,更新對應的元數(shù)據(jù)信息到父節(jié)點中。
掉電保護的具體場景:
  1. 步驟(1)蓝角,(2)阱穗,(3)完成了饭冬,但是(4)沒有完成。因為索引還沒有建立起來揪阶,數(shù)據(jù)雖然寫入了昌抠,但是沒有人知道,文件系統(tǒng)會丟失最新的數(shù)據(jù)鲁僚,保留修改之前的數(shù)據(jù)炊苫。
  2. 步驟(4)過程中掉電了。步驟(4)是更新元數(shù)據(jù)冰沙,元數(shù)據(jù)采用了主備的方式侨艾,并且采取了如下的格式:



    正常的提交流程為:
    (1)提交tag;
    (2)提交data拓挥;
    (3)提交crc唠梨。
    當tag和data提交了,但是CRC沒有提交的時候撞叽,crc就會校驗失敗姻成,這個時候前面crc校驗通過的部分,就會被relocate到一個新的塊愿棋,這樣由于斷電導致的數(shù)據(jù)異常科展,則回退成功。注意:crc校驗的時機糠雨,在提交一個新的commit到對應的元數(shù)據(jù)的時候才睹。

1.2 擦寫均衡

了解擦寫均衡之前,先需要知道littlefs是怎么管理物理block的甘邀,怎么才能申請到一個空閑的block琅攘。

1.2.1 Block管理

為了節(jié)省內容,Littlefs對空閑block的管理采用了滑窗方式松邪,滑窗的大小是可以配置坞琴,默認是32bit,對應32個block的使用情況逗抑。



當文件系統(tǒng)需要申請一個空閑的block的時候剧辐,從lookahead中尋找沒有置位的block,申請成功邮府,則給對應的block位置1荧关。當當前的窗口中的所有block都被占用的時候,就需要滑動窗口了褂傀,一次性滑動窗口大小的距離忍啤,即默認一次滑動32個block。



當窗口滑動了之后仙辟,lookahead中又有了新的空閑的block可以申請同波。
問題來了鳄梅,怎么定義一個block是不是空閑的呢?

一片flash的總的block是有限的未檩,假設其序號從0->N卫枝,lookahead對應的block范圍是I->J,Littlefs會通過lfs_fs_traverse遍歷所有使用到的block讹挎,如果這個block在I->J之間校赤,則說明block被使用了,否則就是空閑的筒溃。

1.2.2 擦寫均衡的實現(xiàn)

通過前面的滑窗機制马篮,可以一定程度上的避免每次操作到的都是同一個片區(qū)的block。但是這還不夠怜奖,因為每次啟動的時候浑测,滑窗都是從block0開始滑動的,這個會導致前面的block使用頻率高于后面的block歪玲。所以迁央,我們需要找到辦法,讓每次啟動的時候滥崩,滑窗的位置都是隨機的岖圈,極致的隨機,就是平均了钙皮。
為此蜂科,littlefs使用了crc作為隨機數(shù),再通過簡單的運算短条,得到了滑窗啟動的時候的起始位置导匣。
問題又來了,crc哪兒來的茸时,干什么的贡定?
Crc就是元數(shù)據(jù)提交的終結符號,用來校驗提交是不是正確的可都,littlefs借用了crc之間相互異或帶來的不確定性來作為滑窗的啟動地址缓待,一定程度上復用了現(xiàn)有的機制達到了隨機的目的。

1.3 文件讀寫

寫入流程:



讀取流程:


?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末汹粤,一起剝皮案震驚了整個濱河市命斧,隨后出現(xiàn)的幾起案子田晚,更是在濱河造成了極大的恐慌嘱兼,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贤徒,死亡現(xiàn)場離奇詭異芹壕,居然都是意外死亡汇四,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門踢涌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來通孽,“玉大人,你說我怎么就攤上這事睁壁”晨啵” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵潘明,是天一觀的道長行剂。 經常有香客問我,道長钳降,這世上最難降的妖魔是什么厚宰? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮遂填,結果婚禮上铲觉,老公的妹妹穿的比我還像新娘。我一直安慰自己吓坚,他們只是感情好撵幽,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著礁击,像睡著了一般并齐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上客税,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天况褪,我揣著相機與錄音,去河邊找鬼更耻。 笑死测垛,一個胖子當著我的面吹牛,可吹牛的內容都是我干的秧均。 我是一名探鬼主播食侮,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼目胡!你這毒婦竟也來了锯七?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤誉己,失蹤者是張志新(化名)和其女友劉穎眉尸,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡噪猾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年霉祸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袱蜡。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡丝蹭,死狀恐怖,靈堂內的尸體忽然破棺而出坪蚁,到底是詐尸還是另有隱情奔穿,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布敏晤,位于F島的核電站巫橄,受9級特大地震影響,放射性物質發(fā)生泄漏茵典。R本人自食惡果不足惜湘换,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望统阿。 院中可真熱鬧彩倚,春花似錦、人聲如沸扶平。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽结澄。三九已至哥谷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間麻献,已是汗流浹背们妥。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勉吻,地道東北人监婶。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像齿桃,于是被迫代替她去往敵國和親惑惶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容