www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > Linux閱碼場
[導(dǎo)讀]日志本文來聊聊文件系統(tǒng)中的日志系統(tǒng),來看一個簡單的日志系統(tǒng)是如何實現(xiàn)的。本文是接著前面的xv6系列,用到的一些前導(dǎo)知識不再說明,沒看的可以先看一下。文件系統(tǒng)設(shè)計中通常要考慮錯誤恢復(fù),這是因為文件系統(tǒng)會涉及對磁盤的多次寫操作,如果在寫的過程中系統(tǒng)崩潰了,就會使得磁盤上的文件系統(tǒng)處于...

日志

本文來聊聊文件系統(tǒng)中的日志系統(tǒng),來看一個簡單的日志系統(tǒng)是如何實現(xiàn)的。本文是接著前面的 xv6 系列,用到的一些前導(dǎo)知識不再說明,沒看的可以先看一下。

文件系統(tǒng)設(shè)計中通常要考慮錯誤恢復(fù),這是因為文件系統(tǒng)會涉及對磁盤的多次寫操作,如果在寫的過程中系統(tǒng)崩潰了,就會使得磁盤上的文件系統(tǒng)處于不一致的錯誤狀態(tài)。

日志就是設(shè)計來解決因為系統(tǒng)崩潰導(dǎo)致的錯誤問題,本文就 來講解怎么實現(xiàn)一個簡單的日志系統(tǒng)。 的日志系統(tǒng)中,文件操作方面的系統(tǒng)調(diào)用并不會直接對磁盤進行寫操作,而是把對磁盤寫操作描述包裝成一個日志寫在磁盤中,當(dāng)該系統(tǒng)調(diào)用執(zhí)行完成之后,再提交一個記錄到磁盤上。

為什么日志可以解決文件系統(tǒng)操作中出現(xiàn)的崩潰呢?如果崩潰發(fā)生在提交之前,那么磁盤上的日志文件就不會被標(biāo)記為已完成,恢復(fù)系統(tǒng)的代碼就會忽視它,磁盤的狀態(tài)就好像寫操作從未進行一樣。如果是在提交之后崩潰的,恢復(fù)程序會重演所有的寫操作。在任何一種情況下,日志文件都使得磁盤操作對于系統(tǒng)崩潰來說是原子操作:在恢復(fù)之后,要么所有的寫操作都完成了,要么一個寫操作都沒有完成。

上面的理論大都來自 文檔,我們能了解到,最為重要的是實現(xiàn)寫操作的原子性,那么怎樣實現(xiàn)呢? 在磁盤上分配了一片日志區(qū),假如現(xiàn)在內(nèi)存中有一個緩存塊準(zhǔn)備同步到磁盤區(qū)域 A, 并不立即將該緩存塊的數(shù)據(jù)寫到磁盤區(qū)域 A,而是先寫到磁盤的日志區(qū)(提交)。如果沒有問題則將日志區(qū)的數(shù)據(jù)寫到相應(yīng)的磁盤區(qū)域 A。如果有問題,在提交之前發(fā)生了崩潰,則恢復(fù)代碼忽略日志信息,區(qū)域 A 根本就沒進行過寫操作,當(dāng)然就能夠保證數(shù)據(jù)的一致性。如果在提交之后發(fā)生了崩潰,則恢復(fù)代碼將日志區(qū)的數(shù)據(jù)重新寫到磁盤區(qū)域 A,也保證了數(shù)據(jù)的一致性。

日志區(qū)也需要相應(yīng)的數(shù)據(jù)結(jié)構(gòu)來組織管理,相關(guān)的結(jié)構(gòu)定義如下:

結(jié)構(gòu)定義

超級塊

struct?superblock?{
??uint?size;?????????//?Size?of?file?system?image?(blocks)?文件系統(tǒng)大小,也就是一共多少塊
??uint?nblocks;??????//?Number?of?data?blocks??數(shù)據(jù)塊數(shù)量
??uint?ninodes;??????//?Number?of?inodes.???//i結(jié)點數(shù)量
??uint?nlog;?????????//?Number?of?log?blocks???//日志塊數(shù)量??
??uint?logstart;?????//?Block?number?of?first?log?block??//第一個日志塊塊號?
??uint?inodestart;???//?Block?number?of?first?inode?block??//第一個i結(jié)點所在塊號
??uint?bmapstart;????//?Block?number?of?first?free?map?block??//第一個位圖塊塊號
};
文件系統(tǒng)的超級塊,超級塊中記錄了文件系統(tǒng)的元信息,比如上述 的超級塊記錄了數(shù)據(jù)塊、i 結(jié)點、日志塊的數(shù)量和第一塊的塊號。

文件系統(tǒng)的總體布局如下:

日志區(qū)位于文件系統(tǒng)的末尾,分為日志頭(位于第一個日志塊)和日志數(shù)據(jù)塊。

日志頭

#define?MAXOPBLOCKS??10??//?max?#?of?blocks?any?FS?op?writes
#define?LOGSIZE?(MAXOPBLOCKS*3)??//?max?data?blocks?in?on-disk?log

struct?logheader?{?????//日志頭部
??int?n;???????????????
??int?block[LOGSIZE];
};
日志頭用來記錄每次日志的大小和位置關(guān)系信息。 來記錄每次日志使用的空間大小,日志空間的總大小記錄在超級塊中(大小的單位是塊),同時 也規(guī)定每次日志使用的塊數(shù)也不能超過 。

是一個 型數(shù)組,元素個數(shù)最多為 ,用來記錄位置關(guān)系。寫入磁盤是先寫入日志區(qū),再寫到磁盤的其他區(qū)域。這個日志區(qū)的磁盤塊和其他區(qū)域的磁盤之間需要有一個映射關(guān)系,這個關(guān)系就記錄在 數(shù)組中。舉個例子: 表示日志塊 記錄的數(shù)據(jù)應(yīng)放在 號磁盤塊中。

struct?log?{
??struct?spinlock?lock;
??int?start;????//日志區(qū)第一塊塊號
??int?size;?????//日志區(qū)大小
??int?outstanding;?//?有多少文件系統(tǒng)調(diào)用正在執(zhí)行
??int?committing;??//?正在提交
??int?dev;?????//設(shè)備,即主盤還是從盤,文件系統(tǒng)在從盤
??struct?logheader?lh;???//日志頭
};
struct?log?log;
這個結(jié)構(gòu)體只存在于內(nèi)存,用來記錄當(dāng)前的日志信息。這個日志信息也是一個公共資源要避免競爭條件所以配了一把鎖。 三個屬性值從超級塊中讀取。其他的信息見注釋,具體含義后面慢慢講解。下面直接來看日志的函數(shù)實現(xiàn):

函數(shù)實現(xiàn)

void?readsb(int?dev,?struct?superblock?*sb)??//讀超級塊
{
??struct?buf?*bp;

??bp?=?bread(dev,?1);??//讀取超級塊數(shù)據(jù)到緩存塊
??memmove(sb,?bp->data,?sizeof(*sb));??//移動數(shù)據(jù)
??brelse(bp);???//釋放緩存塊
}
這個函數(shù)用來讀取超級塊的內(nèi)容,超級塊在第一塊,第零塊是引導(dǎo)塊。調(diào)用 將數(shù)據(jù)從磁盤讀取到緩存塊中,然后將緩存塊中超級塊的數(shù)據(jù)復(fù)制一份到內(nèi)存中定義的超級塊數(shù)據(jù)結(jié)構(gòu)中去,最后再釋放緩存塊的鎖,因為 調(diào)用 獲取了鎖,使用完該緩存塊就該釋放,詳見磁盤那篇文章

void?initlog(int?dev)
{
??if?(sizeof(struct?logheader)?>=?BSIZE)
????panic("initlog:?too?big?logheader");

??struct?superblock?sb;???//定義局部變量超級塊sb
??initlock(
本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉