共計 2057 個字符,預計需要花費 6 分鐘才能閱讀完成。
這篇“Linux 的 I / O 子系統知識點有哪些”文章的知識點大部分人都不太理解,所以丸趣 TV 小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Linux 的 I / O 子系統知識點有哪些”文章吧。
I/O write
I/O read:
read 系統調用的處理分為用戶空間和內核空間處理兩部分。其中,用戶空間處理只是通過 0x80 中斷陷入內核,接著調用其中斷服務例程,即 sys_read 以進入內核處理流程。
對于 read 系統調用在內核的處理,如上圖所述,經過了 VFS、具體文件系統,如 ext2、頁高速緩沖存層、通用塊層、IO 調度層、設備驅動層、和設備層。其中,VFS 主要是用來屏蔽下層具體文件系統操作的差異,對上提供一個統一接口,正是因為有了這個層次,所以可以把設備抽象成文件。具體文件系統,則定義了自己的塊大小、操作集合等。引入 cache 層的目的,是為了提高 IO 效率。它緩存了磁盤上的部分數據,當請求到達時,如果在 cache 中存在該數據且是最新的,則直接將其傳遞給用戶程序,免除了對底層磁盤的操作。通用塊層的主要工作是,接收上層發出的磁盤請求,并最終發出 IO 請求(BIO)。IO 調度層則試圖根據設置好的調度算法對通用塊層的 bio 請求合并和排序,回調驅動層提供的請求處理函數,以處理具體的 IO 請求。驅動層的驅動程序對應具體的物理設備,它從上層取出 IO 請求,并根據該 IO 請求中指定的信息,通過向具體塊設備的設備控制器發送命令的方式,來操縱設備傳輸數據。設備層都是具體的物理設備。
VFS 層:
內核函數 sys_read 是 read 系統調用在該層的入口點。
它根據文件 fd 指定的索引,從當前進程描述符中取出相應的 file 對象,并調用 vfs_read 執行文件讀取操作。
vfs_read 會調用與具體文件相關的 read 函數執行讀取操作,file- f_op.read。
然后,VFS 將控制權交給了 ext2 文件系統。(ext2 在此作為示例,進行解析)
Ext2 文件系統層的處理
通過 ext2_file_operations 結構知道,上述函數最終會調用到 do_sync_read 函數,它是系統通用的讀取函數。所以說,do_sync_read 才是 ext2 層的真實入口。
該層入口函數 do_sync_read 調用函數 generic_file_aio_read,后者判斷本次讀請求的訪問方式,如果是直接 io(filp- f_flags 被設置了 O_DIRECT 標志,即不經過 cache)的方式,則調用 generic_file_direct_IO 函數;如果是 page cache 的方式,則調用 do_generic_file_read 函數。它會判斷該頁是否在頁高速緩存,如果是,直接將數據拷貝到用戶空間。如果不在,則調用 page_cache_sync_readahead 函數執行預讀(檢查是否可以預讀),它會調用 mpage_readpages。如果仍然未能命中(可能不允許預讀或者其它原因),則直接跳轉 readpage,執行 mpage_readpage,從磁盤讀取數據。
在 mpage_readpages(一次讀多個頁) 中,它會將連續的磁盤塊放入同一個 BIO,并延緩 BIO 的提交,直到出現不連續的塊,則直接提交 BIO,再繼續處理,以構造另外的 BIO。
文件的 page cache 結構
圖 5 顯示了一個文件的 page cache 結構。文件被分割為一個個以 page 大小為單元的數據塊, 這些數據塊(頁)被組織成一個多叉樹(稱為 radix 樹)。樹中所有葉子節點為一個個頁幀結構(struct page),表示了用于緩存該文件的每一個頁。在葉子層最左端的第一個頁保存著該文件的前 4096 個字節(如果頁的大小為 4096 字節),接下來的頁保存著文件第二個 4096 個字節,依次類推。樹中的所有中間節點為組織節點,指示某一地址上的數據所在的頁。此樹的層次可以從 0 層到 6 層,所支持的文件大小從 0 字節到 16 T 個字節。樹的根節點指針可以從和文件相關的 address_space 對象(該對象保存在和文件關聯的 inode 對象中)中取得。
mpage 處理機制就是 page cache 層要處理的問題。
通用塊層
在緩存層處理末尾,執行 mpage_submit_bio 之后,會調用 generic_make_request 函數。這是通用塊層的入口函數。
它將 bio 傳送到 IO 調度層進行處理。
IO 調度層
對 bio 進行合并、排序,以提高 IO 效率。然后,調用設備驅動層的回調函數,request_fn,轉到設備驅動層處理。
設備驅動層
request 函數對請求隊列中每個 bio 進行分別處理,根據 bio 中的信息向磁盤控制器發送命令。處理完成后,調用完成函數 end_bio 以通知上層完成。
塊設備驅動
以上就是關于“Linux 的 I / O 子系統知識點有哪些”這篇文章的內容,相信大家都有了一定的了解,希望丸趣 TV 小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注丸趣 TV 行業資訊頻道。