淺析Linux sockfs文件系統(tǒng)
本文主要對(duì)Linux網(wǎng)絡(luò)文件系統(tǒng)的注冊(cè)與掛載過程進(jìn)行分析
一、簡(jiǎn)介
Linux中“萬物皆文件”,socket在Linux中對(duì)應(yīng)的文件系統(tǒng)叫Sockfs,每創(chuàng)建一個(gè)socket,就在sockfs中創(chuàng)建了一個(gè)特殊的文件,同時(shí)創(chuàng)建了sockfs文件系統(tǒng)中的inode,該inode唯一標(biāo)識(shí)當(dāng)前socket的通信。
本文的重點(diǎn)放在sockfs文件系統(tǒng)的注冊(cè)和掛載流程上,以后會(huì)對(duì)socket的底層來龍去脈進(jìn)行詳細(xì)地分析與記錄。
二、三個(gè)核心結(jié)構(gòu)體
1、結(jié)構(gòu)file_system_type
file_system_type結(jié)構(gòu)體代表Linux內(nèi)核的各種文件系統(tǒng),每一種文件系統(tǒng)必須要有自己的file_system_type結(jié)構(gòu),用于描述具體的文件系統(tǒng)的類型,如ext4對(duì)應(yīng)的ext4_fs_type,struct file_system_type結(jié)構(gòu)體如所示:
如struct file_system_type * next結(jié)構(gòu)體成員,所有文件系統(tǒng)的file_system_type結(jié)構(gòu)形成一個(gè)鏈表,在fs/filesystem.c中有一個(gè)全局的文件系統(tǒng)變量變量
在Linux內(nèi)核中sock_fs_type結(jié)構(gòu)定義代表了sockfs的網(wǎng)絡(luò)文件系統(tǒng),如下所示:
2、結(jié)構(gòu) vfs 掛載與結(jié)構(gòu)掛載
每當(dāng)一個(gè)文件系統(tǒng)被安裝時(shí),就會(huì)有一個(gè)vfsmount結(jié)構(gòu)和mount被創(chuàng)建,mount代表該文件系統(tǒng)的一個(gè)安裝實(shí)例,比較舊的內(nèi)核版本中mount和vfsmount的成員都在vfsmount里,現(xiàn)在Linux內(nèi)核將vfsmount改作mount結(jié)構(gòu)體,并將mount中mnt_root, mnt_sb, mnt_flags成員移到vfsmount結(jié)構(gòu)體中了。這樣使得vfsmount的內(nèi)容更加精簡(jiǎn),在很多情況下只需要傳遞vfsmount而已。struct vfsmount如下:
對(duì)于每一個(gè)mount的文件系統(tǒng)都有一個(gè)vfsmount結(jié)構(gòu)來表示,sockfs安裝時(shí)的vfsmount定義如下所示:
結(jié)構(gòu)掛載如下:
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ? ? ?


三、sockfs文件系統(tǒng)的注冊(cè)
Linux內(nèi)核初始化時(shí),執(zhí)行sock_init()函數(shù)登記sockfs,sock_init()函數(shù)如下:
注冊(cè)函數(shù):
注冊(cè)函數(shù)中的find函數(shù)如下,for循環(huán)一開始的file_systems變量就是上面說的注冊(cè)文件系統(tǒng)使用到的全局變量指針,strncmp去比較file_system_type的第一項(xiàng)name(文件系統(tǒng)名)是否和將要注冊(cè)的文件系統(tǒng)名字相同,如果相同返回的P就是指向同名file_system_type結(jié)構(gòu)的指針,如果沒找到則指向NULL。
在返回register_filesystem函數(shù)后,判斷返回值,如果找到重復(fù)的則返回EBUSY錯(cuò)誤,如果沒找到重復(fù)的,就把當(dāng)前要注冊(cè)的文件系統(tǒng)掛到尾端file_system_type的next指針上,串聯(lián)進(jìn)鏈表,至此一個(gè)文件系統(tǒng)模塊就注冊(cè)好了。
四、sockfs文件系統(tǒng)的安裝
在上面的sock_init()函數(shù)中的sock_mnt = kern_mount(&sock_fs_type)開始進(jìn)行安裝。kern_mount函數(shù)主要用于那些沒有實(shí)體介質(zhì)的文件系統(tǒng),該函數(shù)主要是獲取文件系統(tǒng)的super_block對(duì)象與根目錄的inode與dentry對(duì)象,并將這些對(duì)象加入到系統(tǒng)鏈表。kern_mount宏如下所示:
kern_mount_data如下:
調(diào)用:vfs_kern_mount
vfs_kern_mount函數(shù)調(diào)用mount_fs獲取該文件系統(tǒng)的根目錄的dentry,同時(shí)也獲取super_block,具體實(shí)現(xiàn)如下:
其中type->mount()繼續(xù)調(diào)用了sockfs的回調(diào)函數(shù)sockfs_mount
以上函數(shù)進(jìn)行超級(jí)塊、根root、根dentry相關(guān)的創(chuàng)建及初始化操作,其中上面的s->s_d_op =dops就說指向了sockfs_ops結(jié)構(gòu)體,也就是該sockfs文件系統(tǒng)的struct super_block的函數(shù)操作集指向了sockfs_ops。
該函數(shù)表對(duì)sockfs文件系統(tǒng)的節(jié)點(diǎn)和目錄提供了具體的操作函數(shù),后面涉及到的sockfs文件系統(tǒng)的重要操作均會(huì)到該函數(shù)表中查找到對(duì)應(yīng)的操作函數(shù),例如Linux內(nèi)核在創(chuàng)建socket節(jié)點(diǎn)時(shí)會(huì)查找sockfs_ops的alloc_inode函數(shù), 從而調(diào)用sock_alloc_indode函數(shù)完成socket以及inode節(jié)點(diǎn)的創(chuàng)建。
