關於vfs索引節點和具體文件系統索引節點

超級塊、目錄項、索引節點和文件對象是VFS虛擬文件系統的4個最關鍵組成要素,一個inode索引節點唯一的對應一個目錄文件夾或者文件,比如:/home/gliethttp/hello.c,我們想打開其中的hello.c文件,open("/home/gliethttp/hello.c",O_RDWR);硬盤上home文件夾唯一對應一個屬於home文件夾自己的硬inode索引節點片段信息,gliethttp文件夾也同樣在硬盤上唯一對應一個屬於gliethttp文件夾自己的硬inode索引節點片段信息,只不過home和gliethttp對應的硬inode索引節點片段信息表示的爲文件夾,其中存儲在該硬inode片段信息下數據區的內容只有一個文件名,hello.c則不同,雖然hello.c在硬盤上也有一個和hello.c自己唯一對應的硬inode索引節點片段信息,但是它的硬inode索引節點片段信息的數據區主要是用來對文件真實內容進行索引,而不像文件夾的數據區那樣,僅僅用來存儲文件夾的名字;open函數會通過path_walk()調用ext3_lookup()函數從硬盤中將home、gliethttp和hello.c,這三個硬inode索引節點片段信息,讀出來,隨後當即將這些硬inode索引節點片段信息分別重新組織,生成一個表達力更加豐富的,能夠供內核使用起來得心應手的內核全功能inode索引節點【注意:ext3系統中用來存儲文件的硬inode信息片段往往很簡單,僅僅存儲了一個文件必須的幾個關鍵信息,內核要想方便快捷的對文件進行操作,必須在內核內存中基於硬盤上的硬inode索引節點片段,添加進若干操作屬性集,比如:list鏈表等,重新構建一個更加複雜的,應用起來更加靈活的全功能inode索引節點,這個全功能inode索引節點以硬件inode信息片段爲雛形,更加豐富快速的表達硬件inode片段信息對應的文件】.因爲硬inode索引節點片段信息唯一對應一個文件夾或文件,那麼基於硬inode索引節點片段信息的在內核內存中重新組建的全功能inode索引節點也唯一指向那個文件夾或文件,並且在ext3_lookup()組織全功能inode索引節點的時候內核會調用ext3_read_inode()爲該inode分配操作該inode的特定操作函數集,比如dir文件夾的內存全功能inode索引節點對應的inode操作函數集和file文件對象操作函數集如下:
inode->i_op = &ext3_dir_inode_operations;
inode->i_fop = &ext3_dir_operations;
舉個驅動文件樣例,對於像《Linux下LED驅動測試源碼》【文章地址
http://gliethttp.cublog.cn】驅動程序實例中使用到的
[root@gliethttp]# mknod /dev/led c 254 0
/dev文件夾下建立一個字符類型的名爲led的字符設備文件,ext3_read_inode()函數會在內核內存中組建led文件的全功能inode索引節點的時候調用init_special_inode()爲其分配操作該字符設備inode的操作函數集inode->i_fop = &def_chr_fops;這個def_chr_fops集中只實現了一個open函數調用chrdev_open(),(結構體變量:struct file_oprations def_char_fops,以及函數dev_chr_fops()等均可在目錄fs/char_dev.c中找到)
比如:《Linux下LED驅動測試(應用程序)源碼》【文章地址 http://gliethttp.cublog.cn】應用程序實例中用到如下函數打開設備
fd=open("/dev/led",O_RDWR);
ext3硬盤文件系統上的文件led的硬inode索引節點片段會在函數ext3_lookup()中被重新組建到內核內存中,生成一個led文件對應的inode全功能索引節點,並調用chrdev_open()函數,chrdev_open()在執行時會調用kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);函數從所有註冊登記到內核的字符設備驅動中,根據MAJOR主設備號查找led設備所用的驅動,如果找到,filp->f_op = fops_get(p->ops);那麼將使用insmod led命令註冊到內核的驅動程序對應的文件對象操作函數集合賦值給這個current進程對應的filp->f_op,
static struct file_operations gliethttp_led_fops={
owner: THIS_MODULE,
ioctl: led_ioctl,
open: led_open,
release:led_release,
};
所以這時filp->f_op就等於了gliethttp_led_fops,賦值之後,filp->f_op就不再是def_chr_fops了,而被字符驅動程序的gliethttp_led_fops操作集替換了,用戶再次調用open,open動作也就是被導向到直接調用led_open了,以上的inode似乎已經可以勉強的解決文件的讀寫問題了,但對於每次進行文件打開都要進行全功能inode信息組建,着實是一個費時費力的事情,作爲高性能形象代言人--linux內核,速度和高效永遠是內核開發陣營響亮的營歌,也是所有用戶對linux內核的強烈感覺,故而linux引入了目錄項dentry,目錄項使得inode可以安全的停留在內核內存中不被輕易釋放掉,一個目錄項唯一對應一個由ext3_lookup()函數組建到內核內存的全功能inode索引節點,而一個全功能inode索引節點可以被若干個目錄項對應,這也就使得應用更加靈活,目錄項通過hash算法,將成千上萬的哥們兒目錄項們,打散到各個hash短鏈中【對於hash短鏈的理解可以參看《其實hash哈希原理很簡單 》文章地址 http://gliethttp.cublog.cn】hash短鏈的引入讓文件查詢的速度也就被成百上千倍的得到優化提升放大,迅速的找到了一個dentry也就找到了文件夾或文件對應的inode,也就迅速的找到了那個相應的文件夾或文件,也就節省了大家不少的時間.

綜述:一個ext3文件系統硬盤上的硬inode索引節點片段信息,唯一的對應物理文件,這是內核內存中全功能inode索引節點存在的唯一硬件文件來源,硬inode索引節點片段信息存儲在硬盤上,而全功能inode索引節點和目錄項dentry都只是在內核內存中被臨時組建起來,隨着內核的運行,可能會被釋放掉的硬盤上的文件在內核內存中的一個快速索引而已,至於file文件對象,也是一個純內存對象,和硬盤文件無關,當然file對象和硬盤文件存在着的那點關係由file->f_op=inode->f_op文件對象操作集來勉強維繫。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章