溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Linux中怎么實(shí)現(xiàn)一個(gè)文件系統(tǒng)

發(fā)布時(shí)間:2021-08-10 15:17:20 來源:億速云 閱讀:120 作者:Leah 欄目:建站服務(wù)器

Linux中怎么實(shí)現(xiàn)一個(gè)文件系統(tǒng),相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

Linux文件管理從用戶的層面介紹了Linux管理文件的方式。Linux有一個(gè)樹狀結(jié)構(gòu)來組織文件。樹的頂端為根目錄(/),節(jié)點(diǎn)為目錄,而末端的葉子為包含數(shù)據(jù)的文件。當(dāng)我們給出一個(gè)文件的完整路徑時(shí),我們從根目錄出發(fā),經(jīng)過沿途各個(gè)目錄,最終到達(dá)文件。

我們可以對(duì)文件進(jìn)行許多操作,比如打開和讀寫。在Linux文件管理相關(guān)命令中,我們看到許多對(duì)文件進(jìn)行操作的命令。它們大都基于對(duì)文件的打開和讀寫操作。比如cat可以打開文件,讀取數(shù)據(jù),最后在終端顯示:

$cat test.txt

 

對(duì)于Linux下的程序員來說,了解文件系統(tǒng)的底層組織方式,是深入進(jìn)行系統(tǒng)編程所必備的。即使是普通的Linux用戶,也可以根據(jù)相關(guān)的內(nèi)容,設(shè)計(jì)出更好的系統(tǒng)維護(hù)方案。

 
存儲(chǔ)設(shè)備分區(qū)

文件系統(tǒng)的最終目的是把大量數(shù)據(jù)有組織的放入持久性(persistant)的存儲(chǔ)設(shè)備中,比如硬盤和磁盤。這些存儲(chǔ)設(shè)備與內(nèi)存不同。它們的存儲(chǔ)能力具有持久性,不會(huì)因?yàn)閿嚯姸?;存?chǔ)量大,但讀取速度慢。

 

觀察常見存儲(chǔ)設(shè)備。最開始的區(qū)域是MBR,用于Linux開機(jī)啟動(dòng)(參考Linux開機(jī)啟動(dòng))。剩余的空間可能分成數(shù)個(gè)分區(qū)(partition)。每個(gè)分區(qū)有一個(gè)相關(guān)的分區(qū)表(Partition table),記錄分區(qū)的相關(guān)信息。這個(gè)分區(qū)表是儲(chǔ)存在分區(qū)之外的。分區(qū)表說明了對(duì)應(yīng)分區(qū)的起始位置和分區(qū)的大小。

 

我們?cè)赪indows系統(tǒng)常常看到C分區(qū)、D分區(qū)等。Linux系統(tǒng)下也可以有多個(gè)分區(qū),但都被掛載在同一個(gè)文件系統(tǒng)樹上。

數(shù)據(jù)被存入到某個(gè)分區(qū)中。一個(gè)典型的Linux分區(qū)(partition)包含有下面各個(gè)部分:

 

分區(qū)的第一個(gè)部分是啟動(dòng)區(qū)(Boot block),它主要是為計(jì)算機(jī)開機(jī)服務(wù)的。Linux開機(jī)啟動(dòng)后,會(huì)首先載入MBR,隨后MBR從某個(gè)硬盤的啟動(dòng)區(qū)加載程序。該程序負(fù)責(zé)進(jìn)一步的操作系統(tǒng)的加載和啟動(dòng)。為了方便管理,即使某個(gè)分區(qū)中沒有安裝操作系統(tǒng),Linux也會(huì)在該分區(qū)預(yù)留啟動(dòng)區(qū)。

啟動(dòng)區(qū)之后的是超級(jí)區(qū)(Super block)。它存儲(chǔ)有文件系統(tǒng)的相關(guān)信息,包括文件系統(tǒng)的類型,inode的數(shù)目,數(shù)據(jù)塊的數(shù)目。

隨后是多個(gè)inodes,它們是實(shí)現(xiàn)文件存儲(chǔ)的關(guān)鍵。在Linux系統(tǒng)中,一個(gè)文件可以分成幾個(gè)數(shù)據(jù)塊存儲(chǔ),就好像是分散在各地的龍珠一樣。為了順利的收集齊龍珠,我們需要一個(gè)“雷達(dá)”的指引:該文件對(duì)應(yīng)的inode。每個(gè)文件對(duì)應(yīng)一個(gè)inode。這個(gè)inode中包含多個(gè)指針,指向?qū)儆谠撐募鱾€(gè)數(shù)據(jù)塊。當(dāng)操作系統(tǒng)需要讀取文件時(shí),只需要對(duì)應(yīng)inode的"地圖",收集起分散的數(shù)據(jù)塊,就可以收獲我們的文件了。

 

 

最后一部分,就是真正儲(chǔ)存數(shù)據(jù)的數(shù)據(jù)塊們(data blocks)了。

 
inode簡介

上面我們看到了存儲(chǔ)設(shè)備的宏觀結(jié)構(gòu)。我們要深入到分區(qū)的結(jié)構(gòu),特別是文件在分區(qū)中的存儲(chǔ)方式。

文件是文件系統(tǒng)對(duì)數(shù)據(jù)的分割單元。文件系統(tǒng)用目錄來組織文件,賦予文件以上下分級(jí)的結(jié)構(gòu)。在硬盤上實(shí)現(xiàn)這一分級(jí)結(jié)構(gòu)的關(guān)鍵,是使用inode來虛擬普通文件和目錄文件對(duì)象。

 

在Linux文件管理中,我們知道,一個(gè)文件除了自身的數(shù)據(jù)之外,還有一個(gè)附屬信息,即文件的元數(shù)據(jù)(metadata)。這個(gè)元數(shù)據(jù)用于記錄文件的許多信息,比如文件大小,擁有人,所屬的組,修改日期等等。元數(shù)據(jù)并不包含在文件的數(shù)據(jù)中,而是由操作系統(tǒng)維護(hù)的。事實(shí)上,這個(gè)所謂的元數(shù)據(jù)就包含在inode中。我們可以用$ls -l filename來查看這些元數(shù)據(jù)。正如我們上面看到的,inode所占據(jù)的區(qū)域與數(shù)據(jù)塊的區(qū)域不同。每個(gè)inode有一個(gè)唯一的整數(shù)編號(hào)(inode number)表示。

 

在保存元數(shù)據(jù),inode是“文件”從抽象到具體的關(guān)鍵。正如上一節(jié)中提到的,inode儲(chǔ)存由一些指針,這些指針指向存儲(chǔ)設(shè)備中的一些數(shù)據(jù)塊,文件的內(nèi)容就儲(chǔ)存在這些數(shù)據(jù)塊中。當(dāng)Linux想要打開一個(gè)文件時(shí),只需要找到文件對(duì)應(yīng)的inode,然后沿著指針,將所有的數(shù)據(jù)塊收集起來,就可以在內(nèi)存中組成一個(gè)文件的數(shù)據(jù)了。

 數(shù)據(jù)塊在1, 32, 0, ...

inode并不是組織文件的唯一方式。最簡單的組織文件的方法,是把文件依次順序的放入存儲(chǔ)設(shè)備,DVD就采取了類似的方式。但如果有刪除操作,刪除造成的空余空間夾雜在正常文件之間,很難利用和管理。

復(fù)雜的方式可以使用鏈表,每個(gè)數(shù)據(jù)塊都有一個(gè)指針,指向?qū)儆谕晃募南乱粋€(gè)數(shù)據(jù)塊。這樣的好處是可以利用零散的空余空間,壞處是對(duì)文件的操作必須按照線性方式進(jìn)行。如果想隨機(jī)存取,那么必須遍歷鏈表,直到目標(biāo)位置。由于這一遍歷不是在內(nèi)存進(jìn)行,所以速度很慢。

FAT系統(tǒng)是將上面鏈表的指針取出,放入到內(nèi)存的一個(gè)數(shù)組中。這樣,F(xiàn)AT可以根據(jù)內(nèi)存的索引,迅速的找到一個(gè)文件。這樣做的主要問題是,索引數(shù)組的大小與數(shù)據(jù)塊的總數(shù)相同。因此,存儲(chǔ)設(shè)備很大的話,這個(gè)索引數(shù)組會(huì)比較大。

inode既可以充分利用空間,在內(nèi)存占據(jù)空間不與存儲(chǔ)設(shè)備相關(guān),解決了上面的問題。但inode也有自己的問題。每個(gè)inode能夠存儲(chǔ)的數(shù)據(jù)塊指針總數(shù)是固定的。如果一個(gè)文件需要的數(shù)據(jù)塊超過這一總數(shù),inode需要額外的空間來存儲(chǔ)多出來的指針。

 
inode示例

在Linux中,我們通過解析路徑,根據(jù)沿途的目錄文件來找到某個(gè)文件。目錄中的條目除了所包含的文件名,還有對(duì)應(yīng)的inode編號(hào)。當(dāng)我們輸入$cat /var/test.txt時(shí),Linux將在根目錄文件中找到var這個(gè)目錄文件的inode編號(hào),然后根據(jù)inode合成var的數(shù)據(jù)。隨后,根據(jù)var中的記錄,找到text.txt的inode編號(hào),沿著inode中的指針,收集數(shù)據(jù)塊,合成text.txt的數(shù)據(jù)。整個(gè)過程中,我們參考了三個(gè)inode:根目錄文件,var目錄文件,text.txt文件的inodes。

在Linux下,可以使用$stat filename,來查詢某個(gè)文件對(duì)應(yīng)的inode編號(hào)。

 

在存儲(chǔ)設(shè)備中實(shí)際上存儲(chǔ)為:

 

當(dāng)我們讀取一個(gè)文件時(shí),實(shí)際上是在目錄中找到了這個(gè)文件的inode編號(hào),然后根據(jù)inode的指針,把數(shù)據(jù)塊組合起來,放入內(nèi)存供進(jìn)一步的處理。當(dāng)我們寫入一個(gè)文件時(shí),是分配一個(gè)空白inode給該文件,將其inode編號(hào)記入該文件所屬的目錄,然后選取空白的數(shù)據(jù)塊,讓inode的指針指像這些數(shù)據(jù)塊,并放入內(nèi)存中的數(shù)據(jù)。

 
文件共享

在Linux的進(jìn)程中,當(dāng)我們打開一個(gè)文件時(shí),返回的是一個(gè)文件描述符。這個(gè)文件描述符是一個(gè)數(shù)組的下標(biāo),對(duì)應(yīng)數(shù)組元素為一個(gè)指針。有趣的是,這個(gè)指針并沒有直接指向文件的inode,而是指向了一個(gè)文件表格,再通過該表格,指向加載到內(nèi)存中的目標(biāo)文件的inode。如下圖,一個(gè)進(jìn)程打開了兩個(gè)文件。

可以看到,每個(gè)文件表格中記錄了文件打開的狀態(tài)(status flags),比如只讀,寫入等,還記錄了每個(gè)文件的當(dāng)前讀寫位置(offset)。當(dāng)有兩個(gè)進(jìn)程打開同一個(gè)文件時(shí),可以有兩個(gè)文件表格,每個(gè)文件表格對(duì)應(yīng)的打開狀態(tài)和當(dāng)前位置不同,從而支持一些文件共享的操作,比如同時(shí)讀取。

要注意的是進(jìn)程fork之后的情況,子進(jìn)程將只復(fù)制文件描述符的數(shù)組,而和父進(jìn)程共享內(nèi)核維護(hù)的文件表格和inode。此時(shí)要特別小心程序的編寫。

看完上述內(nèi)容,你們掌握Linux中怎么實(shí)現(xiàn)一個(gè)文件系統(tǒng)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI