檔案系統與儲存

區塊 I/O 層(block I/O layer,bio/request)

/ bio = BY-oh /

在檔案系統(它以檔案與偏移量思考)與實際的儲存裝置(它以原始磁區思考)之間,坐著一塊核心,其全部職責是把「讀取這些檔案區塊」變成具體、有效率的裝置操作。它蒐集請求、把它們合併與排序、再交給驅動程式。那塊中間機制就是區塊 I/O 層,而它的核心資料結構是 bio 與 request。

以下是流程。當頁面快取需要讀或寫實際的磁碟區塊時,它提交一個 bio——一個描述一次 I/O 操作的結構:一個方向(讀或寫)、一個目標裝置、一個起始磁區、以及一串要填滿或排空的記憶體頁(一個分散聚集清單,使一次邏輯傳輸能橫跨數個不連續的記憶體頁)。區塊層接過這些 bio、把它們組裝成佇列上的 request。在發出之前,它做兩件聰明事:合併(若兩個待處理的 bio 觸及相鄰磁區,把它們融成一個較大的 request,使裝置做一次大傳輸而非兩次小的)與排序/排程(決定以什麼順序送出 request)。在現代 Linux 上,這是多佇列區塊層(blk-mq),它給每個 CPU 自己的提交佇列,使許多核心能平行提交 I/O 而不爭搶單一個鎖——對能處理巨量並行操作的快速 SSD 與 NVMe 磁碟機至關重要。

為何重要:區塊層正是 I/O 變得有效率之處——合併與排序能把一陣細碎散亂的請求風暴變成少數幾個大型的循序請求,這對吞吐極為要緊。誠實的框架:它把底下的裝置是旋轉磁碟、SATA SSD、NVMe 磁碟機還是網路區塊裝置都抽象掉,把它們全部呈現為一個編了號的固定大小磁區陣列。舊的單佇列設計之所以成為瓶頸,正是因為單一個鎖無法讓一台百萬 IOPS 的 NVMe 裝置忙起來,這就是 blk-mq 存在的全部原因。

頁面快取提交 bio: bio A:讀磁區 100..107 bio B:讀磁區 108..115 <- 相鄰 區塊層把 A+B 合併 -> 一個請求讀磁區 100..115(一次裝置傳輸) blk-mq:每個 CPU 有自己的提交佇列 -> 沒有單一被爭搶的鎖

區塊層把兩個相鄰的 bio 融成一個 request,並在 blk-mq 下讓每個 CPU 平行提交。

區塊層不是裝置驅動程式。它建立、合併並排程請求,再把它們交給一個真正與硬體對話的驅動程式(field n 的主題)。單佇列設計因一個鎖序列化所有提交而扼住了快速 SSD;blk-mq 的每 CPU 佇列修正了這點。

又称
block layerbio layerrequest queue區塊 I/O 層區塊層