本文**自:
technorati 標籤: i/o 子系統
--------------------------------分割線開始--------------------------------
我們含有分析的,是基於2.6.32及其後的核心.
我們在linux上總是要儲存資料,資料要麼儲存在檔案系統裡(如ext3),要麼就儲存在裸裝置裡。我們在使用這些資料的時候都是通過檔案這個抽象來訪問的,作業系統會把我們需要的資料提交給我們,而我們則無需和塊裝置打交道。
從下圖,我們可以清除的看到:
i/o子系統是個層次很深的系統,資料請求從使用者空間最終到達磁碟,經過了複雜的資料流動。
對設驅開發人員或與此相關的設計人員,特別是io很密集,我們就需要搞清楚io具體是如何動作的,免得濫用io和導致設計問題。(
ibm developworks中,〈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 物件中)中取得(更多關於 page cache 的結構內容請參見參考資料)。
mpage處理機制就是page cache層要處理的問題。
通用塊層
在快取層處理末尾,執行mpage_submit_bio之後,會呼叫generic_make_request函式。這是通用塊層的入口函式。
它將bio傳送到io排程層進行處理。
io排程層
對bio進行合併、排序,以提高io效率。然後,呼叫裝置驅動層的**函式,request_fn,轉到裝置驅動層處理。
裝置驅動層
request函式對請求佇列中每個bio進行分別處理,根據bio中的資訊向磁碟控制器傳送命令。處理完成後,呼叫完成函式end_bio以通知上層完成。
--------------------------------分割線結束-----------------------------------
檔案系統學習5 檔案系統IO子系統
io系統 01 io子系統 io系統 02 使用者態的檔案io操作 io系統 03 虛擬檔案系統 vfs io系統 04 節點路徑搜尋 io系統 05 open流程分析 io系統 06 因open建立的結構體關係 io系統 07 io寫流程分析 io系統 08 io讀流程分析 io系統 09 直接i...
Linux磁碟和檔案系統
linux一般使用fdisk來分割槽,fdisk基本支援所有的作業系統。fdisk是基於mbr的分割槽工具,如果使用gpt分割槽的話是不能使用fdisk的。fdisk l可以列出所有安裝的磁碟及其分割槽資訊 cat proc partitions可以檢視分割槽資訊,proc儲存系統的實時資訊 fdi...
Linux磁碟和檔案系統
早期的linux版本使用ext2檔案系統,是一種索引型的檔案系統。檔案系統 filesystem 與磁碟的關係是,將磁碟掛載到檔案系統相應的目錄下面。磁碟的使用必須經過分割 格式化和掛載,相應的命令為fdisk mkfs和mount。通過df命令可以檢視作業系統中磁碟都是掛載在哪些位置的。一般安裝l...