91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

文件系統(tǒng)中的日志系統(tǒng)是如何實(shí)現(xiàn)的

Linux閱碼場(chǎng) ? 來(lái)源:Rand ? 作者:Rand ? 2021-09-29 11:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

日志

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

文件系統(tǒng)設(shè)計(jì)中通常要考慮錯(cuò)誤恢復(fù),這是因?yàn)槲募到y(tǒng)會(huì)涉及對(duì)磁盤(pán)的多次寫(xiě)操作,如果在寫(xiě)的過(guò)程中系統(tǒng)崩潰了,就會(huì)使得磁盤(pán)上的文件系統(tǒng)處于不一致的錯(cuò)誤狀態(tài)。

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

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

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

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

結(jié)構(gòu)定義超級(jí)塊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é)點(diǎn)數(shù)量

uint nlog; // Number of log blocks //日志塊數(shù)量

uint logstart; // Block number of first log block //第一個(gè)日志塊塊號(hào)

uint inodestart; // Block number of first inode block //第一個(gè)i結(jié)點(diǎn)所在塊號(hào)

uint bmapstart; // Block number of first free map block //第一個(gè)位圖塊塊號(hào)

};

文件系統(tǒng)的超級(jí)塊,超級(jí)塊中記錄了文件系統(tǒng)的元信息,比如上述 的超級(jí)塊記錄了數(shù)據(jù)塊、i 結(jié)點(diǎn)、日志塊的數(shù)量和第一塊的塊號(hào)。

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

d350253e-209c-11ec-82a8-dac502259ad0.png

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

日志頭#define MAXOPBLOCKS 10 // max # of blocks any FS op writes#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk logstruct logheader { //日志頭部

int n;

int block[LOGSIZE];

};

日志頭用來(lái)記錄每次日志的大小和位置關(guān)系信息。 來(lái)記錄每次日志使用的空間大小,日志空間的總大小記錄在超級(jí)塊中(大小的單位是塊),同時(shí) 也規(guī)定每次日志使用的塊數(shù)也不能超過(guò) 。

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

struct log {

struct spinlock lock;

int start; //日志區(qū)第一塊塊號(hào)

int size; //日志區(qū)大小

int outstanding; // 有多少文件系統(tǒng)調(diào)用正在執(zhí)行

int committing; // 正在提交

int dev; //設(shè)備,即主盤(pán)還是從盤(pán),文件系統(tǒng)在從盤(pán)

struct logheader lh; //日志頭

};

struct log log;

這個(gè)結(jié)構(gòu)體只存在于內(nèi)存,用來(lái)記錄當(dāng)前的日志信息。這個(gè)日志信息也是一個(gè)公共資源要避免競(jìng)爭(zhēng)條件所以配了一把鎖。 三個(gè)屬性值從超級(jí)塊中讀取。其他的信息見(jiàn)注釋?zhuān)唧w含義后面慢慢講解。下面直接來(lái)看日志的函數(shù)實(shí)現(xiàn):

函數(shù)實(shí)現(xiàn)void readsb(int dev, struct superblock *sb) //讀超級(jí)塊

{

struct buf *bp;

bp = bread(dev, 1); //讀取超級(jí)塊數(shù)據(jù)到緩存塊

memmove(sb, bp-》data, sizeof(*sb)); //移動(dòng)數(shù)據(jù)

brelse(bp); //釋放緩存塊

}

這個(gè)函數(shù)用來(lái)讀取超級(jí)塊的內(nèi)容,超級(jí)塊在第一塊,第零塊是引導(dǎo)塊。調(diào)用 將數(shù)據(jù)從磁盤(pán)讀取到緩存塊中,然后將緩存塊中超級(jí)塊的數(shù)據(jù)復(fù)制一份到內(nèi)存中定義的超級(jí)塊數(shù)據(jù)結(jié)構(gòu)中去,最后再釋放緩存塊的鎖,因?yàn)?調(diào)用 獲取了鎖,使用完該緩存塊就該釋放,詳見(jiàn)磁盤(pán)那篇文章

void initlog(int dev)

{

if (sizeof(struct logheader) 》= BSIZE)

panic(“initlog: too big logheader”);

struct superblock sb; //定義局部變量超級(jí)塊sb

initlock(&log.lock, “l(fā)og”); //初始化日志的鎖

readsb(dev, &sb); //讀取超級(jí)塊

/*根據(jù)超級(jí)塊的信息設(shè)置日志的一些信息*/

log.start = sb.logstart; //第一個(gè)日志塊塊號(hào)

log.size = sb.nlog; //日志塊塊數(shù)

log.dev = dev; //日志所在設(shè)備

recover_from_log(); //從日志中恢復(fù)

}

這個(gè)函數(shù)來(lái)初始化日志的信息,前面應(yīng)該都很好理解,超級(jí)塊中記錄的有一些元數(shù)據(jù),讀取超級(jí)塊來(lái)初始化一些日志信息,比如日志的大小位置。最后一點(diǎn)不太好理解的地方便是 故名思意,從日志中恢復(fù),每次啟動(dòng)調(diào)用初始化函數(shù)它都會(huì)執(zhí)行這個(gè)函數(shù)來(lái)保證文件系統(tǒng)的一致性,關(guān)于這個(gè)函數(shù)我們后面再詳述。

static void install_trans(void)

{

int tail;

for (tail = 0; tail 《 log.lh.n; tail++) {

struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block 讀取日志塊

struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst 讀取日志塊中數(shù)據(jù)本身應(yīng)在的磁盤(pán)塊

memmove(dbuf-》data, lbuf-》data, BSIZE); // copy block to dst 將數(shù)據(jù)復(fù)制到目的地

bwrite(dbuf); // write dst to disk 同步緩存塊到磁盤(pán)

brelse(lbuf); //釋放 lbuf

brelse(dbuf); //釋放 dbuf

}

}

就干了一件事:將磁盤(pán)中的日志塊數(shù)據(jù)復(fù)制到應(yīng)在的磁盤(pán)塊中去,前面文章曾說(shuō)過(guò)針對(duì)一些列的磁盤(pán)操作,都是先在對(duì)應(yīng)的緩存塊中操作再同步到相應(yīng)的磁盤(pán)塊中去。所以先讀取兩部分的數(shù)據(jù)到內(nèi)存中的緩存塊(不一定真的從磁盤(pán)中讀出來(lái),要視磁盤(pán)數(shù)據(jù)在內(nèi)存中是否有緩存),在內(nèi)存中把數(shù)據(jù)復(fù)制過(guò)去,再同步到磁盤(pán)塊中去,最后釋放掉緩存塊。

典型的日志使用方式如下:

begin_op();

。..。..。..。

bp = bread(。..);

bp-》data[。..] = 。..;

log_write(bp);

。..。..。..。

end_op();

和 是一對(duì)兒,配套使用,表明一個(gè)文件系統(tǒng)調(diào)用的開(kāi)始和結(jié)束。通常文件系統(tǒng)調(diào)用就是讀寫(xiě)磁盤(pán)上的數(shù)據(jù),所以同樣的先調(diào)用 讀取數(shù)據(jù),然后修改,但是同步寫(xiě)到磁盤(pán)上不是直接調(diào)用 而是使用 來(lái)替代。為什么這么操作,我們按照上面的順序一個(gè)一個(gè)來(lái)看:

void begin_op(void)

{

acquire(&log.lock);

while(1){

if(log.committing){ //如果日志正在提交,休眠

sleep(&log, &log.lock);

} else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS 》 LOGSIZE){

// this op might exhaust log space; wait for commit. 如果此次文件系統(tǒng)調(diào)用涉及的塊數(shù)超過(guò)日志塊數(shù)上限,休眠

sleep(&log, &log.lock);

} else {

log.outstanding += 1; //文件系統(tǒng)調(diào)用加1

release(&log.lock); //釋放鎖

break; //退出循環(huán)

}

}

}

表明一個(gè)文件系統(tǒng)調(diào)用開(kāi)始,它將一直等待直到日志處于未提交狀態(tài),直到有足夠的日志空間保存當(dāng)前所有調(diào)用的寫(xiě)入。這個(gè)足夠的空間是保守估計(jì)的, 假設(shè)每個(gè)系統(tǒng)調(diào)用可能寫(xiě)入 個(gè)塊, 表示正在執(zhí)行的系統(tǒng)調(diào)用個(gè)數(shù), 就表示加上自身這個(gè)系統(tǒng)調(diào)用,這個(gè)數(shù)乘以 就表示當(dāng)前并發(fā)的系統(tǒng)調(diào)用可能寫(xiě)入的塊數(shù), 表示當(dāng)前的日志空間已經(jīng)使用的塊數(shù),它們兩者之和如果小于日志空間,則可以繼續(xù)下一步,否則等待。

若能繼續(xù)下一步,表示日志空間的空閑區(qū)域足夠容納當(dāng)前系統(tǒng)調(diào)用的寫(xiě)入操作,則執(zhí)行該文件系統(tǒng)調(diào)用,將 數(shù)量加 ,表示當(dāng)前正執(zhí)行的系統(tǒng)調(diào)用個(gè)數(shù)增加 個(gè)。

void log_write(struct buf *b)

{

int i;

if (log.lh.n 》= LOGSIZE || log.lh.n 》= log.size - 1) //當(dāng)前已使用的日志空間不能大于規(guī)定的大小

panic(“too big a transaction”);

if (log.outstanding 《 1) //如果當(dāng)前正執(zhí)行的系統(tǒng)調(diào)用小于1

panic(“l(fā)og_write outside of trans”);

acquire(&log.lock);

for (i = 0; i 《 log.lh.n; i++) {

if (log.lh.block[i] == b-》blockno) // log absorbtion

break;

}

log.lh.block[i] = b-》blockno;

if (i == log.lh.n)

log.lh.n++; //日志空間使用量加1

b-》flags |= B_DIRTY; // prevent eviction 設(shè)置臟位,避免緩存塊直接釋放掉了

release(&log.lock);

}

就是 一個(gè)替代品, 直接設(shè)置緩存塊的臟位然后請(qǐng)求磁盤(pán)同步到磁盤(pán)上去。而 只是設(shè)置緩存塊的臟位并未立即進(jìn)行磁盤(pán)請(qǐng)求,而是后面提交的時(shí)候統(tǒng)一同步寫(xiě)到磁盤(pán)。

同一個(gè)塊在單個(gè)事務(wù)中多次寫(xiě)入的時(shí)候,會(huì)先在 數(shù)組中查找是否記錄了當(dāng)前緩存塊,如果記錄了,就使用當(dāng)前的日志塊,如果沒(méi)有記錄,分配一個(gè)日志塊, 數(shù)組更新信息。這樣操作即使一個(gè)塊在單個(gè)事務(wù)中多次寫(xiě)入,也只會(huì)占用一個(gè)日志塊,節(jié)省了日志空間,這種優(yōu)化操作就叫做吸收。

如果調(diào)用了 之后調(diào)用 釋放緩存塊,這時(shí)候日志還沒(méi)有提交,則可能會(huì)出現(xiàn)緩存塊引用為 0,但數(shù)據(jù)臟的情況,具體例子可參考 函數(shù)。在這兒就回答了磁盤(pán) 一文遺留的一個(gè)問(wèn)題,在 函數(shù)分配緩存塊的時(shí)候一定要尋找引用為 0 且臟位沒(méi)有設(shè)置的緩存塊。因?yàn)榫退憔彺鎵K的引用為 0,只要數(shù)據(jù)臟,則代表該緩存塊仍在使用當(dāng)中。

void end_op(void)

{

int do_commit = 0;

acquire(&log.lock); //取鎖

log.outstanding -= 1; //文件系統(tǒng)調(diào)用減1

if(log.committing) //如果正在提交,panic

panic(“l(fā)og.committing”);

if(log.outstanding == 0){ //如果正在執(zhí)行的文件系統(tǒng)調(diào)用為0,則可以提交了

do_commit = 1;

log.committing = 1;

} else {

// begin_op() may be waiting for log space,

// and decrementing log.outstanding has decreased

// the amount of reserved space.

wakeup(&log); //喚醒因日志空間不夠而休眠的進(jìn)程

}

release(&log.lock);

if(do_commit){ //如果可以提交

// call commit w/o holding locks, since not allowed

// to sleep with locks.

commit(); //提交

acquire(&log.lock); //取鎖

log.committing = 0; //提交完之后設(shè)為沒(méi)有處于提交狀態(tài)

wakeup(&log); //日志空間已重置,喚醒因正在提交和空間不夠而休眠的進(jìn)程

release(&log.lock); //釋放鎖

}

}

基本上是 相反的操作,它表示系統(tǒng)調(diào)用結(jié)束,將 減 1。如果 減為 0,表示當(dāng)前沒(méi)有文件系統(tǒng)調(diào)用在進(jìn)行,則可以提交事務(wù)了:設(shè)置 和 t 屬性為 1,具體提交操作在后面進(jìn)行。

如果 不為 0,則喚醒休眠在 上的進(jìn)程。前面 會(huì)因?yàn)槿罩究臻g可能不夠用而休眠,在這兒?jiǎn)拘???赡苡信笥岩苫螅谶@兒?jiǎn)拘延惺裁从茫?減 1 但是日志空間已經(jīng)被占用了,似乎在這兒?jiǎn)拘褵o(wú)用。這里要注意 中的計(jì)算空間的式子:,這是一個(gè)很保守的估計(jì),當(dāng)前系統(tǒng)調(diào)用完成之后 的值會(huì)變大, 的值會(huì)減 1,因此這個(gè)式子的總和完全可能變小,所以在這兒?jiǎn)拘咽怯凶饔玫摹?/p>

執(zhí)行提交的過(guò)程主要就是調(diào)用 函數(shù),提交之后修改日志提交狀態(tài)為 0 表示并未處于提交狀態(tài),這時(shí)候日志空間也已經(jīng)清空有足夠的日志空間可以使用,所以喚醒休眠在 上的進(jìn)程。

接下來(lái)看具體的日志提交:

static void commit()

{

if (log.lh.n 》 0) {

write_log(); // Write modified blocks from cache to log

write_head(); // Write header to disk -- the real commit

install_trans(); // Now install writes to home locations

log.lh.n = 0;

write_head(); // Erase the transaction from the log

}

}

static void write_log(void) //將緩存塊寫(xiě)到到日志區(qū)

{

int tail;

for (tail = 0; tail 《 log.lh.n; tail++) {

struct buf *to = bread(log.dev, log.start+tail+1); // log block

struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block

memmove(to-》data, from-》data, BSIZE);

bwrite(to); // write the log

brelse(from);

brelse(to);

}

}

static void write_head(void) //將日志頭寫(xiě)到日志區(qū)第一塊

{

struct buf *buf = bread(log.dev, log.start); //讀取日志頭

struct logheader *hb = (struct logheader *) (buf-》data); //類(lèi)型轉(zhuǎn)換

int i;

hb-》n = log.lh.n; //日志記錄大小

for (i = 0; i 《 log.lh.n; i++) {

hb-》block[i] = log.lh.block[i]; //位置信息

}

bwrite(buf); //將日志頭同步到磁盤(pán)

brelse(buf);

}

static void read_head(void) //讀取日志頭信息

{

struct buf *buf = bread(log.dev, log.start); //日志頭在日志區(qū)第一塊

struct logheader *lh = (struct logheader *) (buf-》data); //地址類(lèi)型轉(zhuǎn)換

int i;

log.lh.n = lh-》n; //當(dāng)前日志塊數(shù)

for (i = 0; i 《 log.lh.n; i++) {

log.lh.block[i] = lh-》block[i]; //當(dāng)前日志位置信息

}

brelse(buf);

}

這幾個(gè)函數(shù)應(yīng)該很好理解了,看注釋?xiě)?yīng)該都能明白就不一一解釋了,在這兒主要說(shuō)一些提交的具體過(guò)程:

首先判斷日志頭中的 是否大于 0,大于 0 表示有日志要提交,否則日志為空,不用提交也無(wú)可提交。

如果有日志要提交,則先根據(jù)內(nèi)存中的日志頭中的 數(shù)組記錄的信息,將內(nèi)存中的緩存塊寫(xiě)到日志區(qū)。

然后將內(nèi)存中的日志頭同步到磁盤(pán)的日志頭中去。這一步代表提交點(diǎn),完成這一步表示已提交,反之則沒(méi)有提交。

經(jīng)過(guò)提交點(diǎn)之后,再根據(jù)內(nèi)存中的日志頭中的 數(shù)組記錄的信息,將日志區(qū)的數(shù)據(jù)復(fù)制到磁盤(pán)的其他區(qū)域。

之后將內(nèi)存中的日志頭的 設(shè)為 0,再同步日志頭到磁盤(pán)。表示已完整的完成一次事務(wù)操作,清除日志空間,為下一次事務(wù)做準(zhǔn)備。

static void recover_from_log(void)

{

read_head(); //讀取日志頭

install_trans(); // if committed, copy from log to disk

log.lh.n = 0;

write_head(); // clear the log

}

,從日志中恢復(fù),可以看出這個(gè)函數(shù)與 很相似,只不過(guò) 需要從磁盤(pán)將日志頭讀出,而 的時(shí)候日志頭本身就在內(nèi)存當(dāng)中不用讀取,其他部分一模一樣不再解釋。

這里也解釋了為什么這個(gè)日志是一個(gè) ,可以看出如果能從日志中恢復(fù),它是將提交所做的事情重新做了一遍。

在這兒再來(lái)看看為什么 能夠進(jìn)行錯(cuò)誤恢復(fù),使得磁盤(pán)中的數(shù)據(jù)保持一致性呢?如果在提交之前發(fā)生了崩潰,則磁盤(pán)上的日志不會(huì)被標(biāo)記為已完成,也就是日志頭中的 為 0。因此在進(jìn)行恢復(fù)操作執(zhí)行 函數(shù)時(shí), 讀取日志頭的時(shí)候發(fā)現(xiàn) n 為 0,則執(zhí)行 的時(shí)候根本就不會(huì)進(jìn)入 循環(huán)進(jìn)行實(shí)際的操作。也即如果在提交之前發(fā)生崩潰,對(duì)磁盤(pán)所有的操作都發(fā)生日志區(qū),恢復(fù)代碼直接忽略該日志,不會(huì)將日志中的數(shù)據(jù)同步到磁盤(pán)的其他區(qū)域,也就保證了磁盤(pán)中文件系統(tǒng)的一致性。

如果崩潰發(fā)生在提交之后,則磁盤(pán)中的日志頭 n 不為 0,恢復(fù)代碼將根據(jù) 數(shù)組記錄的信息,循環(huán) n 次把所有使用的日志塊同步到磁盤(pán)的其他區(qū)域。對(duì)磁盤(pán)所有的寫(xiě)入操作先是寫(xiě)入了日志區(qū),恢復(fù)的時(shí)候又從日志區(qū)同步到磁盤(pán)相應(yīng)的其他區(qū)域,這也就保證了磁盤(pán)中數(shù)據(jù)的一致性。

所以因?yàn)槿罩镜拇嬖?,?duì)磁盤(pán)所有的寫(xiě)入操作都先是寫(xiě)到日志區(qū),再同步到磁盤(pán)的其他區(qū)域。使得對(duì)磁盤(pán)的寫(xiě)入操作是一種原子操作,要么寫(xiě)入操作全部完成,要么好像根本就沒(méi)有進(jìn)行寫(xiě)入操作一樣(實(shí)際上日志區(qū)是有寫(xiě)入操作的),因此這種原子寫(xiě)入操作保證了磁盤(pán)文件系統(tǒng)的一致性。

好啦,關(guān)于 的文件系統(tǒng)的日志層就聊到這里,有什么錯(cuò)誤還請(qǐng)批評(píng)指正,也歡迎大家來(lái)同我討論交流學(xué)習(xí)進(jìn)步。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4968

    瀏覽量

    73960
  • 日志
    +關(guān)注

    關(guān)注

    0

    文章

    146

    瀏覽量

    11063

原文標(biāo)題:如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的日志系統(tǒng)

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    RT-Thread ULOG: 創(chuàng)建多個(gè)文件后端并保存不同日志方法 | 技術(shù)集結(jié)

    日志都看不到。這時(shí)候就很有必要把日志文件保存在文件系統(tǒng)中了。RTT軟件包ULOG_FILE這個(gè)包可以實(shí)
    的頭像 發(fā)表于 12-15 19:22 ?4914次閱讀
    RT-Thread ULOG: 創(chuàng)建多個(gè)<b class='flag-5'>文件</b>后端并保存不同<b class='flag-5'>日志</b>方法 | 技術(shù)集結(jié)

    明晚8點(diǎn)|睿擎文件系統(tǒng)實(shí)戰(zhàn):從開(kāi)發(fā)到發(fā)布全流程解析

    文件操作到鏡像發(fā)布,一次直播掌握完整開(kāi)發(fā)流程!在嵌入式系統(tǒng)開(kāi)發(fā),文件系統(tǒng)是數(shù)據(jù)存儲(chǔ)、配置管理和資源訪問(wèn)的核心基礎(chǔ)。然而在實(shí)際開(kāi)發(fā)
    的頭像 發(fā)表于 11-11 11:53 ?641次閱讀
    明晚8點(diǎn)|睿擎<b class='flag-5'>文件系統(tǒng)</b>實(shí)戰(zhàn):從開(kāi)發(fā)到發(fā)布全流程解析

    【直播預(yù)告】下周三晚8點(diǎn)|睿擎文件系統(tǒng)實(shí)戰(zhàn):從開(kāi)發(fā)到發(fā)布全流程解析

    文件操作到鏡像發(fā)布,一次直播掌握完整開(kāi)發(fā)流程!在嵌入式系統(tǒng)開(kāi)發(fā),文件系統(tǒng)是數(shù)據(jù)存儲(chǔ)、配置管理和資源訪問(wèn)的核心基礎(chǔ)。然而在實(shí)際開(kāi)發(fā)
    的頭像 發(fā)表于 11-06 18:05 ?1905次閱讀
    【直播預(yù)告】下周三晚8點(diǎn)|睿擎<b class='flag-5'>文件系統(tǒng)</b>實(shí)戰(zhàn):從開(kāi)發(fā)到發(fā)布全流程解析

    睿擎派文件系統(tǒng)指南:從開(kāi)發(fā)到發(fā)布全流程實(shí)踐 | 技術(shù)解析

    在嵌入式系統(tǒng)開(kāi)發(fā)文件系統(tǒng)扮演著至關(guān)重要的角色,它負(fù)責(zé)數(shù)據(jù)的持久化存儲(chǔ)、配置文件管理和資源訪問(wèn)等核心功能。睿擎平臺(tái)提供了一套完整的文件系統(tǒng)
    的頭像 發(fā)表于 11-05 18:13 ?8096次閱讀
    睿擎派<b class='flag-5'>文件系統(tǒng)</b>指南:從開(kāi)發(fā)到發(fā)布全流程實(shí)踐 | 技術(shù)解析

    使用ulog 寫(xiě)入日志文件系統(tǒng),無(wú)法使用cat命令讀取文件內(nèi)容怎么解決?

    1.我使用ulog+littlefs寫(xiě)入日志日志正常寫(xiě)入,但是沒(méi)法使用cat指令讀取文件內(nèi)容失敗,必須關(guān)掉ulog,才能讀取日志文件顯示的
    發(fā)表于 10-13 06:12

    文件系統(tǒng),使用iar編譯報(bào)錯(cuò),gcc可以正常編譯,為什么?

    文件系統(tǒng),使用iar編譯報(bào)錯(cuò),gcc可以正常編譯,為什么?
    發(fā)表于 09-23 06:54

    技術(shù)貼|【RK3588】ELF 2開(kāi)發(fā)板如何添加exFAT和NTFS文件系統(tǒng)格式

    如何通過(guò)系統(tǒng)配置實(shí)現(xiàn)對(duì)該兩種文件系統(tǒng)的支持,并配置自動(dòng)掛載功能。Windows系統(tǒng)格式化存儲(chǔ)設(shè)備在使用TF卡前,需通過(guò)Windows自帶工具將其格式化為目標(biāo)
    的頭像 發(fā)表于 08-27 17:21 ?3527次閱讀
    技術(shù)貼|【RK3588】ELF 2開(kāi)發(fā)板如何添加exFAT和NTFS<b class='flag-5'>文件系統(tǒng)</b>格式

    Linux三大主流文件系統(tǒng)解析

    還在為選擇哪個(gè)文件系統(tǒng)而糾結(jié)?作為一名摸爬滾打多年的運(yùn)維老鳥(niǎo),我將用最接地氣的方式,帶你徹底搞懂 Linux 三大主流文件系統(tǒng)的奧秘。
    的頭像 發(fā)表于 08-05 17:37 ?1445次閱讀

    飛凌嵌入式ElfBoard ELF 1板卡-文件系統(tǒng)簡(jiǎn)介

    文件系統(tǒng)Journalling Flash File System Version 2是一個(gè)可讀寫(xiě),壓縮,日志文件系統(tǒng)。其功能是管理在MTD設(shè)備上實(shí)現(xiàn)
    發(fā)表于 06-19 17:22

    服務(wù)器數(shù)據(jù)恢復(fù)—重裝系統(tǒng)導(dǎo)致XFS文件系統(tǒng)分區(qū)丟失的數(shù)據(jù)恢復(fù)案例

    。通過(guò)LVM擴(kuò)容的方式將sdc1分區(qū)加入到了root_lv,剩下的sdc2分區(qū)格式化為XFS文件系統(tǒng)。 服務(wù)器重裝系統(tǒng)后,發(fā)現(xiàn)sdc2分區(qū)丟失,無(wú)法訪問(wèn)。
    的頭像 發(fā)表于 06-12 11:20 ?798次閱讀
    服務(wù)器數(shù)據(jù)恢復(fù)—重裝<b class='flag-5'>系統(tǒng)</b>導(dǎo)致XFS<b class='flag-5'>文件系統(tǒng)</b>分區(qū)丟失的數(shù)據(jù)恢復(fù)案例

    服務(wù)器數(shù)據(jù)恢復(fù)—ocfs2文件系統(tǒng)被格式化為Ext4文件系統(tǒng)的數(shù)據(jù)恢復(fù)案例

    服務(wù)器存儲(chǔ)數(shù)據(jù)恢復(fù)環(huán)境&故障: 人為誤操作將Ext4文件系統(tǒng)誤裝入一臺(tái)服務(wù)器存儲(chǔ)上的Ocfs2文件系統(tǒng)數(shù)據(jù)卷上,導(dǎo)致原Ocfs2文件系統(tǒng)被格式化為Ext4文件系統(tǒng)。
    的頭像 發(fā)表于 06-10 12:03 ?726次閱讀
    服務(wù)器數(shù)據(jù)恢復(fù)—ocfs2<b class='flag-5'>文件系統(tǒng)</b>被格式化為Ext4<b class='flag-5'>文件系統(tǒng)</b>的數(shù)據(jù)恢復(fù)案例

    技術(shù)分享 | i.MX8MPlus Journal日志管理系統(tǒng)

    ,該文件系統(tǒng)雖然不如Ubuntu等安裝第三方軟件包方便,但勝在足夠精簡(jiǎn)且運(yùn)行穩(wěn)定,今天主要分享其中運(yùn)行的一種日志管理系統(tǒng),Journal。Journal日志管理
    的頭像 發(fā)表于 05-08 17:23 ?686次閱讀
    技術(shù)分享 | i.MX8MPlus Journal<b class='flag-5'>日志</b>管理<b class='flag-5'>系統(tǒng)</b>

    基于RV1126開(kāi)發(fā)板限制系統(tǒng)日志大小教程

    無(wú)論管理什么系統(tǒng),對(duì)日志文件的監(jiān)控、調(diào)用、管理都是其中重要的一部分。服務(wù)器問(wèn)題的解決都是從查看系統(tǒng)(錯(cuò)誤)日志開(kāi)始的。
    的頭像 發(fā)表于 04-16 11:18 ?736次閱讀
    基于RV1126開(kāi)發(fā)板限制<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>日志</b>大小教程

    如何正確選擇嵌入式文件系統(tǒng)?

    Linux嵌入式系統(tǒng),文件系統(tǒng)和緩存機(jī)制常導(dǎo)致數(shù)據(jù)存儲(chǔ)穩(wěn)定性問(wèn)題。本文通過(guò)案例分析原因,對(duì)比不同文件系統(tǒng)特性,為開(kāi)發(fā)者提供優(yōu)化建議,助力提升數(shù)據(jù)穩(wěn)定性和
    的頭像 發(fā)表于 03-17 11:35 ?1103次閱讀
    如何正確選擇嵌入式<b class='flag-5'>文件系統(tǒng)</b>?

    在stm32cubeprogrammer上燒錄時(shí),取消勾選根文件系統(tǒng),燒錄后發(fā)現(xiàn)sd卡上根文件系統(tǒng)的分區(qū)沒(méi)有了,為什么?

    在修改了linux內(nèi)核后,我想只把bootfs燒錄到sd卡上,而不擦除根文件系統(tǒng)的分區(qū)。 我在stm32cubeprogrammer上燒錄時(shí),取消勾選根文件系統(tǒng),燒錄后發(fā)現(xiàn)sd卡上根文件系統(tǒng)的分區(qū)沒(méi)有了。
    發(fā)表于 03-07 06:38