我們都知道如果要從硬盤里面取數(shù)據(jù),需要告訴控制器從哪里取,取多長(zhǎng)等關(guān)鍵信息,如果這個(gè)步驟由應(yīng)用來(lái)做,則實(shí)在太磨人了。
所以操作系統(tǒng)提供了一個(gè)中間層,對(duì)我們來(lái)說(shuō),只需要記住文件名和路徑,其他的與磁盤塊打交道的事情就交給這個(gè)中間層來(lái)做。這個(gè)中間層即為文件系統(tǒng)
最容易想到的自然是連續(xù)存放。這種方法在隨機(jī)訪問(wèn)的時(shí)候效率最好,只需要知道文件起始位置以及長(zhǎng)度,就可以像數(shù)組一樣訪問(wèn)。
缺點(diǎn)也很明顯,如果一個(gè)文件刪除了,就會(huì)留下很多空白的位置,后面的文件再過(guò)來(lái)填充的時(shí)候,如果填不滿,則會(huì)留下大量的碎片。
所以我們希望一個(gè)文件可以切分成若干小塊,使用鏈表串接起來(lái)。
這樣資源利用率當(dāng)然高了,不過(guò)我們知道鏈表它的訪問(wèn)效率并不高,也就是說(shuō) 每次都得從第一塊開始,沿著鏈表往后找,非常消耗時(shí)間。
我們可以想想在圖書館怎么找書的,是不是有類似一張圖書——位置的對(duì)應(yīng)表,我們按圖索驥即可。于是引入了索引式,使用專門的一個(gè)磁盤塊來(lái)存放文件屬性&文件所占的磁盤塊。這個(gè)塊叫inode。
既然每個(gè)文件都有一個(gè)inode來(lái)描述,每個(gè)目錄當(dāng)然也需要一個(gè)inode,其中存放了目錄的屬性以及這個(gè)目錄內(nèi)容的磁盤塊號(hào)。
比如要讀取/tmp/test.log,查找次序是這樣的:
根目錄inode->根目錄磁盤塊->
tmp目錄inode->tmp目錄磁盤塊->
test.log的 inode->讀取磁盤塊
流程相當(dāng)復(fù)雜,特別在刪除的時(shí)候,很容易就糟了。
比如想刪除/tmp/test.log需要
如果某一步出錯(cuò),就可能出問(wèn)題。為了解決這種問(wèn)題,引入了日志。也就是說(shuō)在操作之間把規(guī)劃列出來(lái),形成日志,然后按照列出來(lái)的規(guī)劃進(jìn)行操作,只有所有的步驟走完了才能擦除日志。
如果在某一步崩潰了,系統(tǒng)重啟的時(shí)候會(huì)再檢查日志項(xiàng),發(fā)現(xiàn)哪些沒(méi)做,則重新來(lái)一遍即可。
我們已經(jīng)解決了怎么存放文件和目錄的問(wèn)題。但是我們還需要知道哪些地方?jīng)]有使用,也就是空閑的塊在那里。也就是說(shuō)把空閑塊管理起來(lái),統(tǒng)一進(jìn)行空間分配。
我們同樣可以把空閑塊組成一個(gè)鏈表,然后分配的時(shí)候就遍歷一下鏈表即可。但是存在一個(gè)問(wèn)題,如果磁盤塊號(hào)是32位,則每個(gè)塊都得花32位的空間,如果空閑塊非常多,則浪費(fèi)極大。
既然我們只是要知道某個(gè)地方是否被占用,而某個(gè)地方只存在占用和未占用兩種可能,不妨使用一張位圖,對(duì)于每個(gè)磁盤塊,如果使用了,則標(biāo)記為1,沒(méi)用就標(biāo)記為0。這樣,每個(gè)磁盤塊只是使用了一位來(lái)標(biāo)記,非常節(jié)省空間。
我們以Linux ext2文件系統(tǒng)為例來(lái)看一下。
硬盤主要由MBR與分區(qū)構(gòu)成。
其中MBR中有引導(dǎo)代碼與磁盤分區(qū)表
引導(dǎo)塊里面有什么?每個(gè)分區(qū)都會(huì)一個(gè)引導(dǎo)塊,如果本分區(qū)里面存放有操作系統(tǒng),則會(huì)通過(guò)引導(dǎo)塊來(lái)進(jìn)行裝載。
磁盤分區(qū)表只有64字節(jié),而每個(gè)分區(qū)項(xiàng)占用16字節(jié),則只能容納4個(gè)分區(qū)。如果我們想有多于4個(gè)分區(qū),則可以把其中一個(gè)設(shè)為擴(kuò)展分區(qū),然后繼續(xù)劃分邏輯分區(qū)即可。
每個(gè)分區(qū)由引導(dǎo)塊和塊組構(gòu)成。
每個(gè)塊組中有:
打個(gè)不太恰當(dāng)?shù)谋确剑鳛槭瘴病?/p>
可以把硬盤看做一個(gè)大倉(cāng)庫(kù),而磁盤控制器就是理貨員,沒(méi)有文件系統(tǒng)之前,外面的人(應(yīng)用)取貨和送貨都需要直接于理貨員打交道,告訴他應(yīng)該放那里,或者從那里取,非常的麻煩。
所以我們又請(qǐng)了一個(gè)倉(cāng)管員(文件系統(tǒng)),由他來(lái)打理整個(gè)倉(cāng)庫(kù),他需要對(duì)倉(cāng)庫(kù)里面放了什么東西,有多少空閑的地方了如指掌,所以外面的人只需要告訴倉(cāng)管員要取什么文件,以及文件存放的路徑即可。
那么倉(cāng)管員是如何管理倉(cāng)庫(kù)的呢?
首先為了簡(jiǎn)化管理,他把若干房間(磁盤塊)合在一起管理,形成簇(塊組)。
然后在簇里面分一些房間專門來(lái)存放每個(gè)文件存放的具體位置,這種專門用來(lái)表示“文件——磁盤塊”的映射關(guān)系的數(shù)據(jù)結(jié)構(gòu)就叫inode。所以說(shuō)如果要取文件的話,則可以先查看目錄的inode,在里面可以找到下一級(jí)目錄的inode號(hào),然后可以去下一級(jí)目錄的inode里面找,一級(jí)一級(jí)的下去,最后可以找到文件inode,即可知道文件存在哪些具體的磁盤塊呢。
那么怎么存放數(shù)據(jù)呢?
倉(cāng)管員把每個(gè)房間用一個(gè)格子表示,如果里面放了東西,則格子標(biāo)1,如果沒(méi)放,則標(biāo)0 。這么通過(guò)這幅位圖,就可以輕松知道那些房間是空余的了。
聯(lián)系客服