- 論壇徽章:
- 13
|
/*
* 內(nèi)核中跟掛載相關(guān)的三個函數(shù):sys_mount()、mount_root()、kem_mount()
* 其中用戶態(tài)可以使用的mount()系統(tǒng)調(diào)用,底層調(diào)用的是sys_mount()函數(shù):主要就是將參數(shù)從用戶空間拷到內(nèi)核空間,然后調(diào)用do_mount()函數(shù)
*
* dev_name: 要掛載的設(shè)備(比如光盤、硬盤)
* dir_name: 要掛載到的目錄(比如/mnt/xxx)
* type: 掛載設(shè)備的文件類型(比如iso9660、ext2)
* flags: 掛載模式:只讀,等
* data: sys_mount()是VFS(框架)的接口,最終會調(diào)用一些具體文件系統(tǒng)的驅(qū)動接口,data由不同驅(qū)動自行解釋
*/
sys_mount_1.png (27.02 KB, 下載次數(shù): 36)
下載附件
2016-10-25 10:16 上傳
/*
* 所謂掛載,就是用一個vfsmount結(jié)構(gòu),建立目標(biāo)目錄dentry與設(shè)備根目錄dentry的"等價(jià)"關(guān)系,下次訪問目標(biāo)目錄時(shí),就是訪問到掛載設(shè)備的根目錄
* 所以該函數(shù)主要做3件事(先不用關(guān)心do_remount()、do_loopback(),后面再分析):
* ① 找到目標(biāo)目錄dentry(path_init()、path_walk(),詳見:http://www.xxx.html)
* ② 找到掛載設(shè)備dentry(get_sb_bdev(),參數(shù)dev_name此時(shí)只是設(shè)備路徑,而不是設(shè)備中的文件系統(tǒng)路徑)
* ③ 分配vfsmount結(jié)構(gòu)建立連接
*/
sys_mount_2.png (169.4 KB, 下載次數(shù): 38)
下載附件
2016-10-25 11:04 上傳
/*
* 可以看出,該函數(shù)純粹通過設(shè)備名稱找對應(yīng)的文件系統(tǒng)類型信息,所以設(shè)備名稱是有規(guī)范的,比如硬盤為hda1等
* file_system_type結(jié)構(gòu)中最關(guān)鍵的是read_super函數(shù)指針,它指向相應(yīng)文件系統(tǒng)驅(qū)動程序提供的超級塊讀取函數(shù)
*
* 內(nèi)核直接支持的文件系統(tǒng)(即直接編譯到內(nèi)核的文件驅(qū)動),以及通過ko文件動態(tài)安裝到內(nèi)核的文件驅(qū)動,都會注冊到file_systems數(shù)組
* 從頁該函數(shù)的過程也自然容易理解了(依賴“設(shè)備驅(qū)動”的知識,暫不深入分析):
* ① 先從file_system找一遍,找到了則返回
* ② 如果步驟①沒返回,則找一下是否有相關(guān)的驅(qū)動,有的話自動安裝并再次查找(可以看出ko文件除了用insmod手動安裝,內(nèi)核也可能在運(yùn)行時(shí)自動安裝)
*/
sys_mount_3.png (14.95 KB, 下載次數(shù): 46)
下載附件
2016-10-25 11:17 上傳
/*
* FS_NOMOUNT:不支持掛載的文件系統(tǒng)(比如一些虛擬文件系統(tǒng))
* FS_REQUIRES_DEV:需要物理基礎(chǔ)的設(shè)備(大部分屬于這種,比如ext2、minix、ufs、iso9660等)
* FS_SINGLE:有些文件系統(tǒng)在內(nèi)存中的超級塊,是按類型建立的(比如一些虛擬文件設(shè)備,同一類型多個設(shè)備內(nèi)存中只會出現(xiàn)一個超級塊)
*
* 除以上情況,一般也是虛擬文件系統(tǒng),暫時(shí)只關(guān)心FS_REQUIRES_DEV的情況,從而對get_sb_bdev()進(jìn)行分析(其實(shí)就是do_mount()需要做的第②件事,通過掛載設(shè)備的超級塊,找到該設(shè)備中文件系統(tǒng)的根目錄dentry):
* VFS系統(tǒng)的很多結(jié)構(gòu),都是基于各種具體驅(qū)動相關(guān)結(jié)構(gòu)的抽象,主要體現(xiàn)在這些結(jié)構(gòu)中的一些函數(shù)指針指向不同,以及在具體操作函數(shù)中對這些抽象結(jié)構(gòu)的函數(shù)指針設(shè)置不同
* get_sb_bdev()函數(shù)一般會執(zhí)行到blkdev_get()→read_super()這個分支,由VFS進(jìn)入具體的驅(qū)動函數(shù),"打開"、讀入超級塊,同時(shí)又在具體的驅(qū)動接口中,將VFS層傳入的抽象結(jié)構(gòu)中的函數(shù)指針,設(shè)置為該驅(qū)動模塊中的函數(shù)
*/
sys_mount_4.png (327.57 KB, 下載次數(shù): 45)
下載附件
2016-10-25 13:19 上傳
sys_mount_5.png (42.68 KB, 下載次數(shù): 39)
下載附件
2016-10-25 13:56 上傳
sys_mount_6.png (23.43 KB, 下載次數(shù): 34)
下載附件
2016-10-25 14:07 上傳
經(jīng)過稍微漫長的過程,終于把掛載設(shè)備的超級塊讀進(jìn)來了,該設(shè)備上文件系統(tǒng)的根目錄dentry也自然可以獲取到,只不過分析過程中,遇到即將進(jìn)入具體驅(qū)動程序的時(shí)候,我們就撤退了,因?yàn)槲募到y(tǒng)的種類非常多,而且不影響對掛載總體過程的理解,可以根據(jù)自己的需要,選擇一種或幾種文件系統(tǒng),比如ext2,將驅(qū)動中具體的接口,與VFS抽象接口對應(yīng)起來,并完整的走一遍。
/*
* 通過這個函數(shù),可以理解一下vfsmount其它成員的作用,以及系統(tǒng)中所有設(shè)備之間的關(guān)系圖
*/
sys_mount_7.png (58.64 KB, 下載次數(shù): 45)
下載附件
2016-10-25 14:22 上傳
總結(jié):掛載的基本道理其實(shí)非常簡單,就是用一個vfsmount結(jié)構(gòu),將掛載設(shè)備的根目錄dentry與掛載目錄dentry關(guān)聯(lián)進(jìn)來,而且內(nèi)核抽象出了VFS層,讓我們可以先清醒的理解完框架,再清醒的攻破各個更具體的環(huán)節(jié)。
|
|