目錄
一、剖析一個塊設(shè)備
二、緩沖區(qū)和緩沖區(qū)頭
三、bio 結(jié)構(gòu)體
四、請求隊列
五、I/O 調(diào)度程序
系統(tǒng)中能夠隨機(不需要按順序)訪問固定大小數(shù)據(jù)片(chunks)的硬件設(shè)備稱作塊設(shè)備,這些固定大小的數(shù)據(jù)片就稱作塊。最常見的塊設(shè)備為硬盤,其他的還有軟盤驅(qū)動器、閃存等,它們都是以安裝文件系統(tǒng)的方式使用的。
另一種基本的設(shè)備類型是字符設(shè)備。字符設(shè)備按照字符流的方式被有序訪問,像串口和鍵盤就屬于字符設(shè)備。
對于這兩種類型的設(shè)備,它們的區(qū)別在于是否可以隨機訪問數(shù)據(jù)。內(nèi)核對塊設(shè)備的管理需要有一個專門提供服務(wù)的子系統(tǒng),對字符設(shè)備的管理則不需要。
一、剖析一個塊設(shè)備
塊設(shè)備中最小的可尋址單位是扇區(qū)。扇區(qū)大小一般是 2 的整數(shù)倍,最常見的是 512 字節(jié)。扇區(qū)的大小是設(shè)備的物理屬性。
在軟件層面上,最小邏輯可尋址單元為塊。塊是文件系統(tǒng)的一種抽象,只能基于塊來訪問文件系統(tǒng)。雖然物理磁盤尋址是按照扇區(qū)進行的,但是內(nèi)核執(zhí)行的所有操作都是按照塊進行的。所以塊不能比扇區(qū)還小,只能倍數(shù)于扇區(qū)大小。
總之,扇區(qū)是設(shè)備的最小尋址單元,也被稱為 “硬扇區(qū)” 或?“設(shè)備塊”;同樣地,塊是文件系統(tǒng)的最小尋址單元,也被稱為 “文件塊” 或 “I/O 塊”。
二、緩沖區(qū)和緩沖區(qū)頭
當一個塊被調(diào)入內(nèi)存時(在讀入后或等待寫出時),它要存儲在一個緩沖區(qū)中。每個緩沖區(qū)與一個塊對應(yīng),它相當于是磁盤塊在內(nèi)存中的表示。一個頁可以容納一個或多個內(nèi)存中的塊。由于內(nèi)核在處理數(shù)據(jù)時需要一些相關(guān)的控制信息(比如一個塊屬于哪個塊設(shè)備,塊對應(yīng)于哪個緩沖區(qū)等),所以每一個緩沖區(qū)都有一個對應(yīng)的描述符 buffer_head 結(jié)構(gòu)體,稱為緩沖區(qū)頭,定義在 <linux/buffer_head.h>,它包含了內(nèi)核操作緩沖區(qū)所需要的全部信息:
但是,將緩沖區(qū)頭作為 I/O 操作單元帶來了兩個弊端:
- 緩沖區(qū)頭是一個很大且不容易控制的數(shù)據(jù)結(jié)構(gòu)體,而且緩沖區(qū)頭對數(shù)據(jù)的操作既不方便也不清晰。
- 它僅能描述單個緩沖區(qū),緩沖區(qū)頭會促使內(nèi)核八大塊數(shù)據(jù)的 I/O 操作分解為多個 buffer_head 結(jié)構(gòu)體進行操作。?
所以后面為塊 I/O 操作引入了一種新型、靈活并輕量級的容器——bio 結(jié)構(gòu)體。
三、bio 結(jié)構(gòu)體
目前內(nèi)核中塊 I/O 操作的基本容器由 bio 結(jié)構(gòu)體表示,定義在 <linux/bio.h>。該結(jié)構(gòu)體代表了正在活動的以片段(segment)鏈表形式組織的塊 I/O 操作。一個片段是一小塊連續(xù)的內(nèi)存緩沖區(qū),而片段鏈表可以使一個緩沖區(qū)分散在內(nèi)存的多個位置上,bio 結(jié)構(gòu)體能對內(nèi)核保證 I/O 操作的執(zhí)行,像這樣的向量 I/O 就是所謂的聚散 I/O。
bio 結(jié)構(gòu)體定義于 <linux/bio.h> 中:
使用 bio 結(jié)構(gòu)體的目的主要是代表正在現(xiàn)場執(zhí)行的 I/O 操作,所以該結(jié)構(gòu)體中的主要域都是用來管理相關(guān)信息的:
bi_io_vec 域指向一個 bio_vec 結(jié)構(gòu)體數(shù)組,該結(jié)構(gòu)體鏈表包含了一個特定 I/O 操作所需要使用到的所有片段。每個 bio_vec 結(jié)構(gòu)都是一個形式為 <page, offset, len> 的向量,它描述的是一個特定的片段:片段所在的物理頁、塊在物理頁中的偏移位置、塊長度。
總之,每一個塊 I/O 請求都通過一個 bio 結(jié)構(gòu)體表示,每個請求包含一個或多個塊,這些塊存儲在 bio_vec 結(jié)構(gòu)體數(shù)組中,bio_vec 結(jié)構(gòu)體描述了每個片段在物理頁中的實際位置,并且像向量一樣被組織在一起。
bio 結(jié)構(gòu)體代表的是 I/O 操作,它包含內(nèi)存中的一個或多個頁;而 buffer_head 結(jié)構(gòu)體代表的是一個緩沖區(qū),它描述的僅僅是磁盤中的一個塊。
四、請求隊列
塊設(shè)備將它們掛起的塊 I/O 請求保存在請求隊列中,該隊列由 request_queue 結(jié)構(gòu)體表示,定義在文件 <linux/blkdev.h> 中,包含一個雙向請求鏈表以及相關(guān)控制信息。
隊列中的請求由結(jié)構(gòu)體 request 表示,一個請求可能要操作多個連續(xù)的磁盤塊,所以每個請求可以由多個 bio 結(jié)構(gòu)體組成。
五、I/O 調(diào)度程序
磁盤尋址是整個計算機中最慢的操作之一,為了縮短尋址時間,Linux 引入了 I/O 調(diào)度程序。
I/O 調(diào)度程序?qū)⒋疟P I/O 資源分配給系統(tǒng)中所有掛起的塊 I/O 請求。I/O 調(diào)度程序通過兩種方法減少磁盤尋址時間:合并與排序。文章來源:http://www.zghlxwxcb.cn/news/detail-678154.html
- 合并指將兩個或多個請求結(jié)合成一個新請求,即如果兩個請求訪問的磁盤扇區(qū)相鄰,那么可以把兩個請求合并為一個請求,這樣可以將 I/O 多次請求的開銷壓縮成一次請求的開銷。
- 排序指將整個請求隊列按扇區(qū)增長方向有序排列,通過保持磁盤頭以直線方向移動,從而縮短所有請求的磁盤尋址時間。這種 I/O 調(diào)度程序也被稱為電梯調(diào)度。
Linux 實際使用的 I/O 調(diào)度程序有如下幾種:文章來源地址http://www.zghlxwxcb.cn/news/detail-678154.html
- Linux 電梯
- 最終期限 I/O 調(diào)度程序
- 預(yù)測 I/O 調(diào)度程序
- 完全公正的排隊 I/O 調(diào)度程序
- 空操作的 I/O 調(diào)度程序
到了這里,關(guān)于Linux內(nèi)核學(xué)習(xí)(十)—— 塊 I/O 層(基于Linux 2.6內(nèi)核)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!