《Linux內核設計與實現》第13章閱讀總結
【edited by 5216lwr】node
1、虛擬文件系統概述
1.虛擬文件系統
(也稱做虛擬文件交換或VF)做爲內核子系統,爲用戶空間程序提供了文件和文件系統相關的接口。經過虛擬文件系統,程序能夠利用標準的Uinx 系統調用對不一樣的文件系統,甚至不一樣介質上的文件系統進行讀寫操做。linux
2.通用原理
- 之因此可使用這種通用接口(VF)對全部類型的文件系統進行操做,是由於內核在它的底層文件系統接口上創建了一個抽象層。
- 該抽象層使Linux 可以支持各類文件系統。爲了支持多文件系統, VFS 提供了一個通用文件系統模型,該模型囊括了任何文件系統的經常使用功能集和行爲。
- 同時實際文件系統也將自身的諸如「如何打開文件」,「目錄是什麼」等概念在形式上與VFS 的定義保持一致。
3.具體示例
- (以write函數爲例)
2、Linux文件系統
1.Unix 使用了四種和文件系統相關的傳統抽象概念:文件、目錄項、索引節點和安裝點
- 文件其實能夠作一個有序字節串,字節串中第一個字節是文件的頭,最後一個字節是文件的
尾;
- 文件經過目錄組織起來。文件目錄比如一個文件夾,用來容納相關文件。由於目錄也能夠包
含其餘目錄,即子目錄,因此目錄能夠層層嵌套,造成文件路徑;因爲VFS 把自錄看成文件對待,因此能夠對目錄執行和文件相同的操做;
- Unix 系統將文件的相關信息和文件自己這兩個概念加以區分,例如訪問控制權限、大小、
擁有者、建立時間等信息,這些被稱做文件的元數據(也就是說,文件的相關數據),被存儲在一個單獨的數據結構中,該結構被稱爲索引節點( inode);
2.VFS對象
- VFS採用的是面向對象的設計思路,使用一組數據結構來表明通用文件對象。包括:
- ·超級塊對象,它表明一個具體的已安裝文件系統。
- 索引節點對象,它表明一個具體文件。
- 目錄項對象,它表明一個目錄項,是路徑的一個組成部分。
- 文件對象,它表明由進程打開的文件。
- 每一個主要對象中都包含一個操做對象,這些操做對象描述了內核針對主要對象可使用的
方法,操做對象做爲一個結構體指針來實現,此結構體中包含指向操做其父對象的函數指針。(其實,對於其中許多方法來講,能夠繼承使用VFS 提供的通用函數,若是通用函數提供的基本功能沒法知足須要,那麼就必須使用實際文件系統的獨有方法填充這些函數指針,使其指向文件系統實例)
3.超級塊對象
- 概述:
- 各類文件系統都必須實現超級塊對象,該對象用於存儲特定文件系統的信息,一般對應於存放在磁盤特定扇區中的文件系統超級塊或文件系統控制塊
- 建立、管理和撤銷超級塊對象的代碼位於文件fs/super.c 中。
- 超級塊對象經過函數alloc_super()建立並初始化。在文件系統安裝時,文件系統會調用該函數以便從磁盤讀取文件系統超級塊,而且將其信息填充到內存中的超級塊對象中。
- 操做:
- 超級塊對象中最重要的一個域是s_op,它指向超級塊的操做函數表。定義在文件<linux/fs.h>中;
- 當文件系統須要對其超級塊執行操做時,首先要在超級塊對象中尋找須要的操做方法;
因爲在C 語言中沒法直接獲得操做函數的父對象,因此必須將父對象以參數形式傳給操做函數;緩存
4.索引結點對象
- 索引節點對象包含了內核在操做文件或目錄時須要的所有信息;
- 一個索引節點表明文件系統中(可是索引節點僅當文件被訪問時,纔在內存中建立〉的一個
文件,它也能夠是設備或管道這樣的特殊文件;
- 操做:
- 和超級塊操做同樣,索引節點對象中的inode_operations 項也很是重要,由於它描述了VFS用以操做索引節點對象的全部方搓,這些方能由文件系統實現;
- 與超級塊相似, 對索引節點的操做調用方式以下:i ->i _op->truncate(i)。其中,i指向給定的索引節點, truncate()函數是由索引節點i 所在的文件系統定義的;
5.目錄項對象
- 爲了方便查找操做, VFS 引入了目錄項的概念。每一個den世y 表明路徑中的一個特定部分;
- 對前一個例子來講,人bin 和vi 都屬於目錄項對象。前兩個是目錄,最後一個是普通文件。必須明確一點: 在路徑中〈包括普通文件在內),每個部分都是目錄項對象
- 目錄項也可包括安裝點。在路徑/mmn/cdrom/foo 中,構成元素/、mmn、foo都屬於
目錄項對象。VFS 在執行目錄操做時〈若是須要的話)會現場建立目錄項對象;
- 目錄項對象由den町結構體表示,定義在文件<linux/dcacbe.h>中;
- 目錄項對象有三種有效狀態:被使用、未被使用和負狀態。
- 被使用狀態:一個被使用的目錄項對應一個有效的索引節點(即d_inode 指向相應的索引節點〉而且代表該對象存在一個或多個使用者(即d_count 爲正值〉
- 未被使用狀態:一個未被使用的目錄項對應一個有效的索引節點( d_inode 指向一個索引節點可是應指明VFS 當前並未使用它( d_count )。該目錄項對象仍然指向一個有效對象,並且被保留在緩存中以便須要時再使用它;
- 一個負狀態的目錄項沒有對應的有效索引節點( d_inode 爲NULL ),由於索引節點已被刪除了,或路徑再也不正確。
- 目錄項緩存
- 目的:若是VFS 層遍歷路徑名中全部的元素並將它們逐個地解析成目錄項對象,還要到達最深層目錄,將是一件很是費力的工做,會浪費大量的時間。因此內核將目錄項對象緩存在目錄項緩存(簡稱dcache )中。
- 包含部分:
- 目錄項操做
- dentry _operation 結構體指明瞭VFS 操做目錄項的全部方法。該結構定義在文件<lin皿/dcache.h>中:
-
- int d_ revalidate(struct dentry *dentry,struct namidata•);該函數判斷目錄對象是否有效• VFS 準備從dcache 中使用一個目錄項肘,會調用該函數。(大部分文件系統將該方法置NULL,由於它們認爲dcache 中的目錄項對象老是有效的。)
- int d hash(struct dentry dentry,struct qstr *name);該函數爲目錄項生成散列值,當目錄項須要加入到散列表中肘, VFS 調用該函數。
- int d_compare(struct dentry •dentry,struct qstr namel,struct qstr name2);VFS 調用該函數來比較namel 和name2 這兩個文件名
- int d_dele t e (struct dentry *dentry);當目錄項對象的d_count 計數值等於0 時, VFS 調用該函數。注意使用該函數須要加dcache_lock 鎖和目錄項的d_lock
- void d_rel ease(struct dentry *dentry);當目錄項對象將要被釋放時, VFS 調用該函數,默認狀況下,它什麼也不傲
- void d_ iput(struct dentry dentry,struct inode inode);當一個目錄項對象丟失了其相關的索引節點時(也就是說磁盤索引節庚、被刪除了), VFS 調用該函數
6.文件對象
- 文件對象包含如訪問模式, 當前偏移等信息;文件操做常見的系統調用read()、write()等也很相似;
- 文件對象僅僅在進程觀點上表明已打開文件,它反過來指向目錄項對象〈反過來指向索
引節點〉,其實只有目錄項對象才表示巳打開的實際文件。雖然一個文件對應的文件對象不是惟
一的,但對應的索引節點和目錄項對象無疑是惟一的;
- 文件操做
- 具體的文件系統能夠爲每一種操做作專門的實現,或者若是存在通用操做,也可使用通用操做
7.文件系統相關的數據結構
- 除了以上幾種VFS 基礎對象外,內核還使用了另一些標準數據結構來管理文件系統的其餘相關數據。第一個對象是file_system_ type, 用來描述各類特定文件系統類型;第二個結構體是vfsmount,用來描述一個安裝文件系統的實例。
- file_system_ type 結構體被定義在<linux/fs.h>中
- get_sb()函數從磁盤上讀取超級塊,而且在文件系統被安裝時,在內存中組裝超級塊對象。剩餘的函數描述文件系統的屬性。
- 每種文件系統,無論有多少個實例安裝到系統中,仍是根本就設有安裝到系統中,都只有一個file_system_ type 結構。
- vfsmount 結構被定義在<linux/mount.h>中
- 理清文件系統和全部其餘安裝點闊的關係,是維護全部安裝點鏈表中最複雜的工做。vfsmount 結構體中維護的各類鏈表就是爲了可以跟蹤這些關聯信息。
8.和進程相關的數據結構
如下三個數據結構將VFS 層和系統的進程緊密聯繫在一塊兒數據結構
- file_ struct 結構體定義在文件<linux/fdtable.h>中。該結構體由進程描述符中的files 目錄項指向。全部與單個進程(per-process)的相關的信息〈如打開的文件及文件描述符〉都包含在其中;
- fs_struct. 該結構由進程描述符的fs域指向。它包含文件系統和進程相關的信息,定義在文件<linux/fs_ struct.h>中;
- 是namespace 結構體=定義在文件<linux/mmt_namespace.h>中,由進程描述符中的mmt_namespace 域指向。2 .4 版內核之後,單進程命名空間被加入到內核中,它使得每個進程在系統中都看到惟一的安裝文件系統一一不只是惟一的根目錄,並且是惟一的文件系統層次結構。
總結
本章主要是圍繞虛擬文件系統——VFS展開的其一系列對象及操做方法的描述。VFS層提供給不一樣文件系統一個統一的實現框架,並且也提供了能和標準系統調用交互工做的統一接口;這樣一來,基於各類不一樣版本、不一樣架構的Linux系統的工做就變得簡單、通用。架構