Linux文件系統(tǒng)解析
時(shí)間:2021-08-19 16:35:41
手機(jī)看文章
掃描二維碼
隨時(shí)隨地手機(jī)看文章
[導(dǎo)讀]文件系統(tǒng)定義在計(jì)算機(jī)出現(xiàn)之前其實(shí)就有文件系統(tǒng)的概念了,此時(shí)的文件系統(tǒng)指的是用于管理(存儲(chǔ)和檢索)紙質(zhì)文件的系統(tǒng),而在計(jì)算機(jī)發(fā)明之后,文件系統(tǒng)逐漸指的是管理存儲(chǔ)介質(zhì)的系統(tǒng),它通過(guò)簡(jiǎn)單的接口給用戶,方便用戶使用存儲(chǔ)設(shè)備。在學(xué)習(xí)Linux的時(shí)候,我們通常會(huì)看到這樣一句話,Linux中一...
文件系統(tǒng)定義
在計(jì)算機(jī)出現(xiàn)之前其實(shí)就有文件系統(tǒng)的概念了,此時(shí)的文件系統(tǒng)指的是用于管理(存儲(chǔ)和檢索)紙質(zhì)文件的系統(tǒng),而在計(jì)算機(jī)發(fā)明之后,文件系統(tǒng)逐漸指的是管理存儲(chǔ)介質(zhì)的系統(tǒng),它通過(guò)簡(jiǎn)單的接口給用戶,方便用戶使用存儲(chǔ)設(shè)備。在學(xué)習(xí) Linux 的時(shí)候,我們通常會(huì)看到這樣一句話,Linux中一切皆文件,也就是說(shuō),不管是普通的文件和目錄,還是包括塊設(shè)備、管道、socket等,也都是交給文件系統(tǒng)去管理的。文件系統(tǒng)是操作系統(tǒng)中負(fù)責(zé)管理持久數(shù)據(jù)的子系統(tǒng),換言之,也就是負(fù)責(zé)把用戶的文件存到磁盤(pán)硬件中,它是一個(gè)磁盤(pán)上的目錄結(jié)構(gòu),是一個(gè)組織文件的方法,并且在一個(gè)磁盤(pán)上,可以包含一個(gè)或者多個(gè)文件系統(tǒng)。下面,我們從用戶的角度和操作系統(tǒng)的角度兩個(gè)層面來(lái)闡述文件系統(tǒng)的相關(guān)概念。用戶角度
要認(rèn)識(shí) Linux 的文件系統(tǒng),從分區(qū)和目錄結(jié)構(gòu)說(shuō)起,首先我們先來(lái)看下windows,這是大多數(shù)人使用最多的一個(gè)操作系統(tǒng),當(dāng)打開(kāi)我的電腦的時(shí)候,映入眼簾的是大致是這樣一個(gè)一張圖:也就是說(shuō)在 windows 下,磁盤(pán)被分為了 C 盤(pán), D 盤(pán)。。。。這樣的一個(gè)目錄結(jié)構(gòu)。那對(duì)于?Linux
呢,它的目錄結(jié)構(gòu)是長(zhǎng)啥樣,它有一個(gè)根目錄,而系統(tǒng)下的所有目錄都是從根目錄分離出去的,我們可以在?Ubuntu
終端運(yùn)行如下命令來(lái)查看Linux
的目錄結(jié)構(gòu)。tree?-L?1?/
上述中,tree
表示將當(dāng)前目錄以樹(shù)的結(jié)構(gòu)展示,-L
表示的是要顯示當(dāng)目錄的第幾層,1
表示的是要顯示到第一層,最后面的?/
表示的也就是Linux
的根目錄,也就是說(shuō)當(dāng)前命令就是顯示根目錄下第一層目錄的信息,最終得到的結(jié)果如下所示:為了更好地理解每個(gè)目錄所代表的意思,我們看如下所示的內(nèi)容:/
|----bin?????---------------->?文件系統(tǒng)的起始位置,稱之為根
|----boot????---------------->?存放系統(tǒng)啟動(dòng)時(shí)讀取的文件,包括系統(tǒng)核心文件
|----dev?????---------------->?存放設(shè)備文件接口,如打印機(jī),硬盤(pán)等外圍設(shè)備
|----etc?????---------------->?存放與系統(tǒng)設(shè)置和管理相關(guān)的文件,如用戶賬號(hào)、密碼等
|????|
|----home????----------------->?存放用戶專屬目錄
|----lib?????----------------->?存放一些共享的函數(shù)庫(kù)
|----misc????----------------->?一個(gè)空目錄,供管理員存放公共雜物
|----proc????----------------->?存放系統(tǒng)核心和執(zhí)行程序之間的信息
|----root????----------------->?系統(tǒng)管理員(超級(jí)用戶)專用目錄
|----sbin????----------------->?與?/bin?類似,存放用于系統(tǒng)引導(dǎo)和管理命令,通常供?root?使用?
|----tmp?????----------------->?臨時(shí)目錄,供任何用戶存放臨時(shí)文件
|----usr?????----------------->?此目錄包含許多子目錄,用來(lái)存放系統(tǒng)命令和程序等信息
|----var?????----------------->?存放經(jīng)常變動(dòng)的文件,如日志文件,臨時(shí)文件,電子郵箱
說(shuō)到這,就有必要再說(shuō)一下?Linux
下的路徑問(wèn)題了,在Linux
中,Linux
的路徑分為絕對(duì)路徑和相對(duì)路徑- 絕對(duì)路徑:指的是一個(gè)文件或者目錄從根目錄開(kāi)始的完整的路徑
- 相對(duì)路徑:是指一個(gè)文件或者目錄相對(duì)于向前工作目錄的路徑
- 任何不以
/
和~
開(kāi)始的路徑均為相對(duì)路徑
Linux
的文件類型的,Linux 內(nèi)一切皆文件,那么對(duì)于 Linux 來(lái)說(shuō),其具有哪些文件類型呢,其主要有如下四種:- 普通文件
- 目錄文件
- 鏈接文件:其作用類似于?
windows
下的快捷方式,它本身不包含內(nèi)容,而是指向其他的文件或目錄 - 設(shè)備文件:存放在?
/dev
目錄下,如:hda,hdb,sda。。。
Linux
啟動(dòng)的時(shí)候,首先掛載的是根文件系統(tǒng),之后可以自動(dòng)或者手動(dòng)掛載其他文件系統(tǒng),這些文件系統(tǒng)要掛載到掛載點(diǎn)上,與虛擬文件系統(tǒng)和通用塊設(shè)備層建立聯(lián)系。掛載,指的就是將設(shè)備文件中的頂級(jí)目錄連接到 Linux 根目錄下的某一目錄(最好是空目錄),訪問(wèn)此目錄就等同于訪問(wèn)設(shè)備文件。上述就是基于用戶的角度對(duì)文件系統(tǒng)進(jìn)行了一個(gè)概述,接下來(lái)從操作系統(tǒng)的角度,更進(jìn)一步地闡述操作系統(tǒng)。
操作系統(tǒng)角度
文件系統(tǒng)的層次
在上述中,闡述掛載的時(shí)候說(shuō)到一個(gè)概念,就是說(shuō)?Linux
在啟動(dòng)的時(shí)候,首先掛載的是根文件系統(tǒng),然后再自動(dòng)或者手動(dòng)掛載其他文件系統(tǒng),這也是Linux
中支持不同文件系統(tǒng)的原因,而支持各種不同文件系統(tǒng)的這種機(jī)制又是什么呢?說(shuō)到這里,就有必要提到Linux
的虛擬文件系統(tǒng)了,再敘述它的概念之前,我們先以宏觀的角度來(lái)看一下?Linux
下的文件系統(tǒng)的一個(gè)結(jié)構(gòu):由上圖可以知道,整個(gè)文件系統(tǒng)體系分為了三個(gè)層面,用戶層,內(nèi)核層,硬件層,用戶層是通過(guò)API通過(guò)系統(tǒng)調(diào)用調(diào)用的方式訪問(wèn)虛擬文件系統(tǒng)。在內(nèi)核層,我們可以看到虛擬文件系統(tǒng)下連接了各種類型的文件系統(tǒng),其是對(duì)不同的文件系統(tǒng)的抽象,為上層應(yīng)用提供了統(tǒng)一的 API 接口;上圖內(nèi)核層還有一層是各個(gè)文件系統(tǒng)之下的一層,這一層的作用是隱藏了不同硬件設(shè)備之間的細(xì)節(jié),為內(nèi)核提供了統(tǒng)一的 IO 操作接口。下面我們對(duì)整個(gè)文件系統(tǒng)從下到上對(duì)各個(gè)層的作用進(jìn)行一個(gè)闡述:- Device Driver(硬盤(pán)驅(qū)動(dòng)):常見(jiàn)的硬盤(pán)類型有
PATA,SATA
,在Linux
中,對(duì)于硬盤(pán)提供的驅(qū)動(dòng)模塊一般都存放在內(nèi)核目錄樹(shù)drivers/ata
中,而對(duì)于一般通用的硬盤(pán)驅(qū)動(dòng),可能會(huì)直接被編譯到內(nèi)核中。 - 通用塊設(shè)備層(General Block Device Layer):不同的硬盤(pán),會(huì)提供不同的 IO 接口,對(duì)于內(nèi)核來(lái)講,這種雜亂的接口是不利于管理的,因此就把這些接口進(jìn)行了抽象,形成了一個(gè)統(tǒng)一的對(duì)外接口,這樣就不管你是什么存儲(chǔ)設(shè)備,操作他們的IO接口并沒(méi)有什么區(qū)別。
- 文件系統(tǒng)層:目前大多數(shù)
Linux
使用的是ex4
,與此同時(shí),btrfs
也呼之欲出 - 虛擬文件系統(tǒng):正如不同的存儲(chǔ)設(shè)備具有不同的 IO 接口,那么不同的文件系統(tǒng)也具有不用的 API,內(nèi)核想實(shí)現(xiàn)的是不管是什么文件系統(tǒng),都采用的是相同的 API 進(jìn)行操作,所以 VFS 就做了一個(gè)抽象,提供了統(tǒng)一的 API 接口,使之可以對(duì)不同的文件系統(tǒng)采用同樣的操作。
文件的使用
上述中,我們介紹了文件系統(tǒng)的層次,那么基于這樣一個(gè)層次,我們又應(yīng)該如何使用文件呢?下圖是一個(gè)使用文件的流程圖:與其對(duì)應(yīng)的代碼也比較簡(jiǎn)單:fd?=?open(name,?flag);????/*?打開(kāi)文件?*/
...
write(fd,?...);???????????/*?寫(xiě)數(shù)據(jù)?*/
...
close(fd);????????????????/*?關(guān)閉文件?*/
上述就是往一個(gè)文件中寫(xiě)數(shù)據(jù)的步驟,使用open
系統(tǒng)調(diào)用打開(kāi)文件,open
的參數(shù)中包含文件的路徑名和文件名,使用write
寫(xiě)數(shù)據(jù),其中write
使用open
所返回的文件描述符,使用完文件后,用close
系統(tǒng)關(guān)閉文件,避免資源的泄露。在打開(kāi)了一個(gè)文件后,操作系統(tǒng)會(huì)跟蹤進(jìn)程打開(kāi)的所有文件,也就是說(shuō)操作系統(tǒng)為每個(gè)進(jìn)程維護(hù)一個(gè)打開(kāi)文件表,文件表里的每一項(xiàng)代表的是文件描述符,所以說(shuō)文件描述符是打開(kāi)文件的標(biāo)識(shí)。操作系統(tǒng)在打開(kāi)文件表中維護(hù)著打開(kāi)文件的狀態(tài)和信息:- 文件指針:系統(tǒng)跟蹤上次讀寫(xiě)位置作為當(dāng)前文件位置的指針,這個(gè)指針對(duì)于打開(kāi)文件的某個(gè)進(jìn)程來(lái)說(shuō)是唯一的;
- 文件打開(kāi)計(jì)數(shù)器:文件關(guān)閉時(shí),操作系統(tǒng)必須重用其打開(kāi)文件表目錄,否則表內(nèi)空間就不夠。因?yàn)槎鄠€(gè)進(jìn)程可能打開(kāi)同一個(gè)文件,所以系統(tǒng)在刪除打開(kāi)文件條目之前,必須等待最后一個(gè)進(jìn)程關(guān)閉文件,該計(jì)數(shù)器跟蹤打開(kāi)和關(guān)閉數(shù)量,當(dāng)該計(jì)數(shù)為 0 時(shí),系統(tǒng)關(guān)閉文件,刪除該條目;
- 文件磁盤(pán)位置:大多數(shù)文件操作都需要系統(tǒng)修改文件的數(shù)據(jù),該信息保存在內(nèi)存中,以免每個(gè)操作都從磁盤(pán)中讀?。?/span>
- 訪問(wèn)權(quán)限:每個(gè)進(jìn)程打開(kāi)文件都需要又一個(gè)訪問(wèn)模式(創(chuàng)建、只讀、讀寫(xiě)、添加等),該信息保存在進(jìn)程的打開(kāi)文件表中。
文件系統(tǒng)的IO類型
根據(jù)文件系統(tǒng)的讀寫(xiě)差異,可以將IO分為四種類型:- 緩沖 I/O:是指利用標(biāo)準(zhǔn)庫(kù)緩存來(lái)加速文件的訪問(wèn),而標(biāo)準(zhǔn)庫(kù)內(nèi)部再通過(guò)系統(tǒng)調(diào)度訪問(wèn)文件。
- 非緩沖I/O:是指直接通過(guò)系統(tǒng)調(diào)用來(lái)訪問(wèn)文件,不再經(jīng)過(guò)標(biāo)準(zhǔn)庫(kù)緩存
此處標(biāo)準(zhǔn)庫(kù)緩存指的是利用棧、隊(duì)列等一些數(shù)據(jù)結(jié)構(gòu)進(jìn)行的資源調(diào)度,而不是頁(yè)緩存。無(wú)論是否是緩沖IO,都會(huì)通過(guò)系統(tǒng)調(diào)用頁(yè)緩存來(lái)減少IO次數(shù)根據(jù)是否利用操作系統(tǒng)的頁(yè)緩存,可以把文件I/O分為直接I/O與非直接I/O
- 直接I/O:是指跳過(guò)操作系統(tǒng)的頁(yè)緩存,直接跟文件系統(tǒng)交互來(lái)訪問(wèn)文件
- 非直接I/O:文件讀寫(xiě)的時(shí)候,先要經(jīng)過(guò)系統(tǒng)的頁(yè)緩存,然后再由內(nèi)核或者是額外的系統(tǒng)調(diào)用,真正寫(xiě)入存儲(chǔ)設(shè)備
通常,我們的 IO 都是非直接I/O根據(jù)應(yīng)用程序是都阻塞自身運(yùn)行,可以把文件 I/O 分為阻塞 I/O 和非阻塞 I/O
- 阻塞I/O,是指應(yīng)用程序執(zhí)行 I/O 操作之后,如果沒(méi)有獲得響應(yīng),就會(huì)阻塞當(dāng)前的線程,自然不能執(zhí)行其他任務(wù)
- 非阻塞I/O,是指應(yīng)用程序執(zhí)行 I/O 操作之后,不會(huì)阻塞當(dāng)前的線程,可以繼續(xù)執(zhí)行其他的任務(wù),隨后再通過(guò)輪詢或者事件通知的形式,獲得調(diào)用的結(jié)果
通常情況下I/O都是阻塞的。網(wǎng)絡(luò)編程中是非阻塞的I/O,用在網(wǎng)絡(luò)套接字的 I/O 中根據(jù)是否等待響應(yīng)結(jié)果,把文件分為同步IO和異步IO
- 同步IO:應(yīng)用程序在執(zhí)行IO操作之后,要一直等到整個(gè)IO完成后,才獲得 IO 響應(yīng)
- 異步IO:是指應(yīng)用程序在執(zhí)行IO操作之后,不用等待完成,可以繼續(xù)做之后的事情,等到 IO 完成的時(shí)候,會(huì)通過(guò)事件通知的方式,告訴應(yīng)用程序
文件的存儲(chǔ)
Linux
中所有文件都有一個(gè)唯一與之對(duì)應(yīng)的索引節(jié)點(diǎn),索引節(jié)點(diǎn)記錄了文件的元數(shù)據(jù),操作系統(tǒng)不是通過(guò)文件名,而是通過(guò)索引節(jié)點(diǎn)來(lái)管理文件,用目錄項(xiàng)來(lái)描述文件之間的關(guān)系。索引節(jié)點(diǎn),也被稱之為是inode,用來(lái)記錄文件的元數(shù)據(jù),元數(shù)據(jù)就包括:node編號(hào)、文件大小、訪問(wèn)權(quán)限、修改日期、數(shù)據(jù)的位置等。目錄項(xiàng),也被稱為dentry
,用來(lái)記錄文件的名字、索引節(jié)點(diǎn)指針及與其他目錄項(xiàng)的關(guān)聯(lián)關(guān)系。多個(gè)關(guān)聯(lián)的目錄項(xiàng),也就構(gòu)成了文件系統(tǒng)的目錄結(jié)構(gòu)。因此,索引節(jié)點(diǎn)相當(dāng)?shù)挠谖募闹羔?,目錄?xiàng)維護(hù)著文件的樹(shù)型關(guān)系下面是文件存儲(chǔ)各個(gè)部分邏輯關(guān)系的一個(gè)示意圖:上圖中,超級(jí)塊用來(lái)存儲(chǔ)著整個(gè)文件系統(tǒng)的狀態(tài),索引節(jié)點(diǎn)區(qū)用來(lái)存儲(chǔ)索引節(jié)點(diǎn),數(shù)據(jù)塊區(qū)用來(lái)存儲(chǔ)文件的數(shù)據(jù),他們之間的關(guān)系在圖中也很清除了,就不進(jìn)行贅述了。總結(jié)
Linux
是一個(gè)很龐大也很優(yōu)秀的系統(tǒng),在嵌入式行業(yè)也應(yīng)用廣泛,筆者對(duì)于?Linux
的接觸不深,這也是最近對(duì)于學(xué)習(xí)?Linux
文件系統(tǒng)時(shí)的一個(gè)總結(jié),如果文中出現(xiàn)問(wèn)題,歡迎各位及時(shí)給我提出來(lái)呀,我將不勝感激~