天天看點

大話存儲系列7——檔案系統和IO處理流程

1、檔案系統

在早期的計算機系統中,每個程式都必須自己管理磁盤,在磁盤中放自己的資料,程式需要直接和磁盤控制器打交道。有多少個程式要利用磁盤,就有多少個磁盤互動啟動接口。

在沒有檔案系統的計算機上,如果一個程式要向磁盤上存儲一些自己的資料,那麼這個程式隻能自己調用磁盤控制器啟動(無VM的情況下),或者調用VM提供的接口,對磁盤寫資料。而寫完資料後,很有可能被其他程式的資料覆寫掉。引入檔案系統後,各個程式之間都通過檔案系統接口通路磁盤,所有被寫入的資料都稱為一個檔案,有着自己的名字,是一個實體。而且其他程式寫入的資料,不會将其他人的檔案資料覆寫掉,因為檔案系統會保障這一點。

檔案系統是作業系統用于明确磁盤或分區上的檔案的方法和資料結構;即在磁盤上組織檔案的方法。也指用于存儲檔案的磁盤或分區,或檔案系統種類。作業系統中負責管理和存儲檔案資訊的軟體機構稱為檔案管理系統,簡稱檔案系統。檔案系統由三部分組成:與檔案管理有關軟體、被管理檔案以及實施檔案管理所需資料結構。從系統角度來看,檔案系統是對檔案存儲器空間進行組織和配置設定,負責檔案存儲并對存入的檔案進行保護和檢索的系統。具體地說,它負責為使用者建立檔案,存入、讀出、修改、轉儲檔案,控制檔案的存取,當使用者不再使用時撤銷檔案等。

更多檔案系統知識請參考部落格:http://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/

2、IO處理流程

IO Manager是作業系統核心的一個子產品,專門用來管理IO,并協調檔案系統、卷、磁盤驅動程式各個子產品之間的運作。整個流程解釋如下:

**某個時刻,某個應用程式調用檔案系統接口,準備寫入某檔案從某個位元組開始的若幹位元組。

**IO Manger 最終将這個請求發送給檔案系統子產品。

**檔案系統将某個檔案對應的邏輯偏移映射成卷的LBA位址偏移。

**檔案系統向IO Manager 請求調用卷管理軟體子產品的接口。

卷管理軟體将卷對應的LBA位址偏移翻譯映射成實際實體磁盤對應的LBA 位址偏移,并請求調用磁盤控制器驅動程式。

**IO Manger 想磁盤控制器驅動程式請求将對應LBA位址段的資料從記憶體中寫入某塊實體磁盤。

Windows作業系統中(以Windows2000/XP為例),一個典型的I/O請求要通過一系列複雜的操作實作:

讨論Windows 系統的I/O操作的流程之前,不得不提及Windows的I/O系統結構。簡單說來,從虛拟機的角度來說,Windows的I/O系統是一個層層封裝的虛拟機。Windows在系統核心中,對裝置進行了數層封裝:直接建構在裝置上的是硬體抽象層(HAL),在此之上的是裝置驅動程式,然後是I/O系統(I/O管理器、電源管理、WDM、WMI例程等);同時還有許多在使用者态運作的系統服務如WMI服務,友善應用程式管理I/O裝置。正因為有這種複雜的層次結構,統一管理、相容成百上千不同種類的系統裝置才成為可能。各個抽象層次把硬體結構上的多樣性屏蔽掉,使使用者能夠按照一個統一的方式進行I/O操作。由于這裡主要讨論I/O處理流程,I/O系統的結構不做細緻闡述。

以下以打開一個檔案對象的過程為例,說明Windows I/O請求的處理流程:

打開檔案對象(File Object)

子系統調用一個I/O系統服務,打開一個有名字的檔案。

I/O管理器(I/O Manager)調用對象管理器(Object Manager)查找這個檔案并幫助它找到所有相關的符号連結。同時也調用安全引用螢幕(Security Reference Monitor)檢查這個子系統是否有打開這個檔案對象的權限。

如果這個檔案所在的卷還沒有裝入,那麼I/O管理器暫時挂起這個請求,調用其他檔案系統,直到裝有這個檔案的卷裝入,然後I/O管理器恢複剛才挂起的請求。

I/O管理器為檔案打開請求的IRP初始化配置設定記憶體。對于驅動程式而言,檔案打開請求等價于一個"create"請求。

I/O管理器調用檔案系統驅動程式,向它發送IRP。檔案系統驅動程式通路它在IRP中的I/O堆棧單元(I/O stack location)以決定要進行什麼操作,檢查參數,決定是否需要通過cache通路檔案。如果不需要,在IRP中建立更低一級驅動程式的I/O堆棧單元。

各級驅動程式處理IRP完成這個I/O操作請求,會調用I/O管理器和其他系統元件提供的核心态支援例程。

驅動程式在IRP中設定I/O狀态塊(指明操作是否成功或錯誤代碼),并将IRP傳回到I/O Manager。

I/O管理器從IRP中獲得I/O狀态,通過被保護的子系統将狀态資訊傳回到原始調用者處。

I/O管理器釋放已經完成任務的IRP。

如果操作成功,I/O管理器傳回這個檔案對象的句柄到子系統;否則傳回相應的失敗狀态。

大話存儲系列7——檔案系統和IO處理流程

如果打開成功,子系統就可以通過句柄來對這個裝置進行各種I/O操作。其他操作的工作流程與此類似。I/O管理器會根據不同的請求類型産生相應的IRP發送到相應的驅動程式中執行特定的操作。

以上處理流程雖然複雜,但去掉一些細節後,總脈絡是清晰的:I/O請求先陷入到系統核心,從上依層次向下将指令傳到裝置,執行結果依次向上傳回到調用程序,切換回使用者态。

整個流程中,有幾個重要的資料結構:

檔案對象(File Object):檔案對象是一種邏輯上的對象,它并不僅僅可以代表檔案,事實上它可以代表許許多多不同的實體裝置(鍵盤、列印機、螢幕……當然也可以代表檔案)。它事實上提供的是一種基于記憶體共享的實體資源表示法。每個檔案對象對應一個句柄,使用者程式通過這個句柄實作各種I/O操作。具體說,通過寫入/查詢特定的記憶體區段的,即可實作和實體裝置的通訊。Windows所有的I/O操作都通過這種虛拟的檔案對象進行,它隐藏了I/O操作目标的實作細節,為各種不同的實體裝置提供了一個統一的操作接口。

驅動程式對象(Driver Object)和裝置對象(DeviceObject):驅動程式對象代表系統中一個獨立的驅動程式,并且為I/O記錄每個驅動程式的排程例程的位址(入口點);裝置對象代表系統中的一個實體、邏輯或虛拟的裝置(注意,并不一定是實體裝置!)并描述其特征。

總體上看,可以認為驅動程式對象是在功能上的抽象(對應某個“操作”),裝置對象是結構上的抽象(對應某個“裝置”)。完成某個操作通常需要用到多個裝置,是以驅動程式對象通常有多個與它相關的裝置對象。

盡管驅動程式對象和裝置對象所封裝的功能和裝置是各種各樣的,但它們都有統一的模型和接口,是以I/O管理器可以統一對它們進行管理和調用,而不用在意其具體内部結構的不同。

I/O請求包(IRP)是I/O系統用來存儲處理I/O請求所需資訊(例如請求的類型和大小、是同步請求還是異步請求、指向緩沖區的指針和進展狀态資訊等)的地方。由前面的例子可以看到,在整個系統核心中的I/O處理流程中,所有的調用/傳回/控制資訊都是由IRP傳遞的。它在I/O請求開始時由I/O管理器建立,在I/O處理完成後被釋放,它是I/O進行中負責資訊傳遞的最主要資料結構,即所謂以IRP驅動的I/O處理機制。

以上四種資料結構完整的抽象出了一個I/O請求的方方面面,它們在邏輯上把形形色色的I/O操作都統一起來,使使用者可以不理會具體實作的細節,用幾乎同樣的方式實作各種I/O操作。

在整個I/O系統中,I/O管理器無疑是非常重要的,具有核心地位。顧名思義,它負責所有I/O請求的排程和管理工作。根據請求的不同内容,選擇相應的驅動程式對象,裝置對象,并生成、發送、釋放各種不同的IRP。整個I/O處理流程是在它的指揮下完成的。

另外,完成I/O操作還需要有許多系統中其他服務的支援,總體上被稱為驅動程式支援例程。

大體流程概括如下圖(課本P317頁圖7.12所描述的也是這個結構):

大話存儲系列7——檔案系統和IO處理流程

事實上由于I/O操作種類繁多,它們有不同的需求和特點,是以Windows提供了不同的I/O操作選項。主要的I/O操作類型有:同步I/O和異步I/O,快速I/O(注意:快速I/O模式比較特殊,不使用IRP),映射檔案I/O和檔案高速緩存,分散/集中I/O。各種I/O操作類型的内部處理步驟是很不一樣的。同時,單層和多層的驅動程式也有不同的執行政策。這些涉及到過多的細節和Windows驅動程式模型(WDM),在此不更多的展開讨論。

雖然具體到每一個I/O請求處理政策會各有不同,但總的來說,涉及到的操作對象和資料結構就是前面提到的那些。而且總的處理脈絡仍然是:I/O請求先陷入到系統核心,從上依層次向下将指令傳到裝置,執行結果依次向上傳回到調用程序,切換回使用者态。

參考資料:

l  《作業系統教程》

l  《MSDN Library》 DDK部分

繼續閱讀