認識磁盤
- 扇區 (sector)和 磁道(track):
下圖顯示的是一個盤面,盤面中一圈圈灰色同心圓爲一條條磁道,從圓心向外畫直線,可以將磁道劃分爲若干個弧段,每個磁道上一個弧段被稱之爲一個扇區(圖踐綠色部分)。扇區是磁盤的最小組成單元,通常是512字節。(由於不斷提高磁盤的大小,部分廠商設定每個扇區的大小是4096字節)
- 磁頭 (head) 和 柱面(cylinder):
硬盤通常由重疊的一組盤片構成,每個盤面都被劃分爲數目相等的磁道,並從外緣的“0”開始編號,具有相同編號的磁道形成一個圓柱,稱之爲磁盤的柱面。磁盤的柱面數與一個盤面上的磁道數是相等的。由於每個盤面都有自己的磁頭,因此,盤面數等於總的磁頭數。 如下圖
磁盤的使用
盤塊:一層抽象
磁盤驅動負責由 盤塊 到 CHS 的轉換
磁盤訪問時間中一大部分是尋道時間。
很明顯如果按照盤塊讀取,會大大提高讀寫速度,而盤塊就是連續的扇區構成。
Linux 0.11 盤塊大小是兩個扇區。
請求隊列:二層抽象
FCFS
所以爲什麼不把移動過程中應該把經過的請求處理掉…
SSTF
短尋道優先,容易出現飢餓問題,尋道時間長的可能得不到執行。
SCAN(電梯算法)
SSTF + 中途不回折
C-SCAN(電梯算法)
多個進程共同使用磁盤
add_request()
將請求插入隊列中,形成電梯隊列:
IN_ORDER(s1,s2)
,先比較柱面號,再比較扇區號,s1<s2
爲true
。
從前往後掃描:
IN_ORDER(temp,req) || !IN_ORDER(tmp,tmp->next) && IN_ORDER(req,temp->next)
拆解爲:IN_ORDER(temp,req) && IN_ORDER(req,temp->next)
或 !IN_ORDER(tmp,tmp->next) && IN_ORDER(req,temp->next)
生磁盤的使用總結
怎麼得到盤塊號?——文件
文件:第三層抽象
文件:建立字符流到盤塊集合的映射關係
連續結構:
假如要找第 200 - 212 字符的盤塊號,需要知道起始塊位置,系統中塊大小固定。
映射表:FCB
鏈式結構:
起始塊號爲 1找到 10(test.c 的第 0 塊) ,讀入 10 找到 17(test.c 的第 1 塊),讀入 17 找到 9 (test.c 的第2塊),讀入 9 找到 -1結束(test.c 的第3塊)。
索引結構
答案是 A
最後一層抽象:文件系統
文件系統
操作系統用一定方式維護這些文件集合,就是文件系統。
文件系統是操作系統用於明確存儲設備或分區上的文件的方法和數據結構;即在存儲設備上組織文件的方法。
目錄樹
很明顯,如果全放在一層,雜亂且使用不便,集合劃分或分治形成的樹狀結構優化了該問題。
實現目錄
如果找到 a 的FCB,我們就可以找到 a 對應的 盤塊,所以目錄的實現最重要的就是要找到文件的 FCB。
目錄應該也是文件,如my
下有三個目錄文件:data,cont,mail
,所以my
的數據塊應該保存這三個目錄文件的FCB,三個目錄保存各自目錄下的文件的 FCB,遞歸解析。
FCB數組的首項就是根目錄的FCB。
藍色部分儲存了必要的信息:引導塊(是否是引導磁盤),超級塊,inode位圖,盤塊位圖。
目錄解析的實現
open()
將路徑名做處理之後,對於目錄的解析在get_dir()
get_dir()
從根目錄開始
根目錄的inode
在init
進程中,調用iget
iget()
read_inode()
需要知道 FCB數組之前的長度,所以要獲得超級塊中的信息,計算可得block
。
find_entry
這個循環是遍歷當前目錄下的所有項
目錄解析整體過程
首先用 iget(1)
找到 inode,放在PCB中,遇到 ‘/’ 把當前FCB的數據塊,從中取出根目錄的目錄項,結構爲<name,block>
,得到索引節點號,再調用iget(block)
找到下一級目錄。直到解析完畢返回目標目錄的inode
。