linux kernel 2009-07-14 16:30:37 閱讀83 評論0 字號:大中小 訂閱
前面說(shuō)過(guò),只要知道文件的索引節點(diǎn)號,就可以得到那個(gè)文件。但是我們在操作文件時(shí),從沒(méi)聽(tīng)說(shuō)誰(shuí)會(huì )拿著(zhù)索引節點(diǎn)號來(lái)操作文件,我們只知道文件名而已。它們是如何"和諧"起來(lái)的呢?linux把目錄也看成一種文件,里面記錄著(zhù)文件名與索引節點(diǎn)號的對應關(guān)系。比如在ext3文件系統中,如果文件是一個(gè)目錄,那么它的內容就是一系列ext3_dir_entry_2的結構
struct ext3_dir_entry_2 {
__u32 inode; /* Inode number */
__u16 rec_len; /* Directory entry length */
__u8 name_len; /* Name length */
__u8 file_type;
char name[EXT3_NAME_LEN]; /* File name */
};
舉個(gè)例子,比如要打開(kāi)/home/test/hello.c。首先,找到‘/’,讀入其內容,找到名為"home"的文件的索引節點(diǎn)號,打開(kāi)/home這個(gè) "文件",讀入內容,找到名為 "test" 的的文件的索引節點(diǎn)號,同理,再打開(kāi)文件"/home/test",找到找到名為"hello.c”的文件的索引節點(diǎn)號,最后就得到 /home/test/hello.c了。這就是path_walk()函數的原理。
其中,根據一個(gè)文件夾的inode,和一個(gè)文件名來(lái)獲取該文件的inode結構的函數,就叫lookup,它是inode_operations里面的函數。
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
lookup,顧名思義,就是查找,比如查查在test這個(gè)文件夾下,有沒(méi)有叫hello.c的文件,有的話(huà),就從存儲介質(zhì)中讀取其inode結構。并用dentry- >d_inode指向它。所以,我們只要知道了文件的路徑和名字,總可以從根目錄開(kāi)始,一層一層的往下走,定位到某一個(gè)文件。
superblock與vfsmount
接下來(lái)還要介紹兩個(gè)數據結構,superblock和vfsmount。super_block結構是從所有具體的文件系統所抽象出來(lái)的一個(gè)結構,每一個(gè)文件系統實(shí)例都會(huì )有一對應super_block結構。比如每一個(gè)ext2的分區就有一個(gè)super_block結構,它記錄了該文件系統實(shí)例(分區)的某些描述性的信息,比如該文件系統實(shí)例的文件系統類(lèi)型,有多大,磁盤(pán)上每一塊的大小, 還有就是super_operations。它與inode,dentry一樣,只是某些內容在內存中的映像。就ext2文件系統而言,設備上的超級塊為 ext2_super_block。由于sysfs是虛擬的文件系統,獨一無(wú)二, 并且只能被mount一次,sysfs的super_block結構是sysfs_sb。sysfs_sb也是動(dòng)態(tài)的從內存中生成的。
還有要提一下super_operations,它也算是VFS的一個(gè)接口。實(shí)現一個(gè)文件系統file_operations, dentry_operations, inode_operations, super_operations這四個(gè)結構都要實(shí)現。
把一個(gè)設備安裝到一個(gè)目錄節點(diǎn)時(shí)要用一個(gè)vfsmount的作為連接件。vfsmount結構定義如下:
struct vfsmount {
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
..........
}
對 于某個(gè)文件系統實(shí)例,內存中super_block和vfsmount都是唯一的。比如,我們將某個(gè)掛載硬盤(pán)分區mount -t vfat /dev/hda2 /mnt/d。實(shí)際上就是新建一個(gè)vfsmount結構作為連接件,vfsmount->mnt_sb = /dev/hda2的超級塊結構;vfsmount->mntroot = /dev/hda2的"根"目錄的dentry;vfsmount->mnt_mountpoint = /mnt/d的dentry; vfsmount->mnt_parent = /mnt/d所屬的文件系統的vfsmount。并且把這個(gè)新建的vfsmount連入一個(gè)全局的hash表mount_hashtable中。
從 而我們就可以從總根’/’開(kāi)始,沿著(zhù)dentry往下找。假如碰到一個(gè)某個(gè)目錄的dentry是被mount了的,那么我們就從 mount_hashtable表中去尋找相應的vfsmount結構 (函數是lookup_mnt())。然后我們得到vfsmount ->mnt_root,就可以找到mount在該目錄的文件系統的"根"dentry結構。然后又繼續往下走,就可以暢通無(wú)阻了。
關(guān)于path_walk()的代碼我就不貼了,太長(cháng)了。其實(shí)懂了原理后再去看,很簡(jiǎn)單,跟看故事會(huì )差不多。我當年就是看完這個(gè)函數后,信心倍增阿。pathwalk,不管前面是高速公路,或是泥濘的鄉間小路,我們都要走到底。
聯(lián)系客服