十四 塊I O層

2022-08-29 19:09:17 字數 1604 閱讀 2220

系統中能夠隨機訪問固定大小資料片的硬體裝置稱作塊裝置,這些固定大小的資料片稱為塊。最常見的塊裝置是硬碟、還有軟盤驅動器、光碟機盒快閃儲存器等。他們都是以安裝檔案系統的方式使用的。

字元裝置按照位元組流的方式有序訪問,如鍵盤和串列埠。

14.1 剖析乙個塊裝置

塊裝置中最小的可定址單元是扇區。扇區大小一般是2的整數倍,最常見的是512位元組。扇區的大小是裝置的物理屬性,扇區是所有塊裝置的基本單元——塊裝置無法對比它還小的單元進行定址和操作,儘管許多塊裝置能夠一次對多個扇區進行操作。很多cd-rom盤的扇區都是2kb大小。

雖然物理磁碟定址按照扇區級別進行的,但是核心執行的所有磁碟操作都是按照塊進行的。由於扇區是裝置的最小可定址單元,所以塊不能比扇區小,只能數倍於扇區大小。核心要求塊的大小是2的倍數且不能超過頁的長度。所以通常塊的大小是512位元組、1kb或4kb。

14.2 緩衝區和緩衝區頭

當乙個塊被調人記憶體時,它要儲存在乙個緩衝區中。每個緩衝區對應乙個塊它相當與磁碟塊在記憶體中的表示。每個緩衝區都有乙個對應的描述符。該描述符用buffer_head結構體表示,稱作緩衝區頭,它包含了核心操作緩衝區所需要的全部資訊。

struct buffer_head

14.3.1 io向量

bi_io_vec域指向乙個bio_vec結構體鍊錶,該鍊錶包含了乙個特定io操作所需要使用到的所有片段。每個bio_vec結構都是乙個形式為的向量,它描述乙個特定的片段:片段所在物理頁、塊在物理頁中的偏移位置、從給定偏移量開始的長度。

在每個給定的塊io操作中,bi_vcnt域用來描述bi_io_vec所指向的vio_vec陣列中向量數目。當塊io操作執行完畢後,bi_idx域指向陣列的當前索引。

每乙個塊io請求都通過乙個bio結構體表示。每個請求包含乙個或多個塊。這些塊儲存在bio_vec結構體陣列中。這些結構體描述了每個片段在物理頁中的實際位置,並且像向量一樣被組織在一起。io操作的第乙個片段有b_io_vec結構體所指向,其他片段在其後依次放置,公有bi_vcnt個片段。當塊io開始執行請求、需要使用各個片段時,bi_idx域會不斷更新,從而總指向當前片段。

bi_cnt域用於記錄bio結構體的使用計數,如果該域值減為0,就應該撤銷該bio結構體,並釋放它占用的記憶體。

void bio_get(struct bio *bio);

void bio_put(struct bio *bio);

14.3 新老方法比較

1、bio結構體很容易處理高階記憶體,因為它處理的是物理頁而不是直接指標

2、bio亦可以代表普通頁io,同時也可以代表直接io(不通過頁快取記憶體的操作)

3、bio結構體便於執行分散-集中塊io操作,操作中的資料可取自多個物理頁面

4、bio相比緩衝區頭屬於輕量級結構體。因為它只需要包含塊io操作所需要的資訊,不用包含於緩衝區本省相關的不必要資訊。

14.4 請求佇列

塊裝置將他們掛起的塊io請求儲存在請求佇列中,該佇列由reques_queue結構表示。通過核心中像檔案系統這樣高層的**將請求加入到佇列中。請求佇列只要不為空,佇列對應的塊裝置驅動程式就會從佇列頭獲取請求,然後將其送入對應的塊裝置上去。

佇列其中的請求由結構體request表示。因為乙個請求可能要操作多個連續的磁碟塊,所以每個請求可以由多個bio結構組成。

14.5 io排程程式

linux核心設計與實現 塊I O層

小結 1.塊i o層的資料結構 bio 表示活動的i o操作 buffer head 表示塊到頁的對映 request 具體的i o請求 2.i o請求的簡單宣告歷程 請求佇列的產生 處理 排程 3.i o排程程式 linus deadline cfq noop 14.4 請求佇列 14.5 i o...

python總結(十四) IO

1.讀取檔案寫法 常用寫法如下 try f open path to file r print f.read finally if f f.close 每次這樣太繁瑣,改為 with open path to file r as f print f.read 呼叫read 會一次性讀取檔案的全部內容...

塊I O排程程式

最近在看 linux核心設計與實現 這本書,寫些東西記錄一下學習過程。塊裝置最突出的特點是可以隨機訪問固定大小的資料片,這些固定大小的資料片稱為塊,塊裝置通過安裝檔案系統來訪問。注意塊裝置都有自己的物理最小定址單元 如扇區 但是在檔案系統下,其有著最小邏輯可定址單元 塊,不要搞混淆了。與塊裝置相對的...