歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

Linux那些事兒之我是Sysfs(8)一起散散步

前面說過,只要知道文件的索引節點號,就可以得到那個文件。但是我們在操作文件時,從沒聽說誰會拿著索引節點號來操作文件,我們只知道文件名而已。它們是如何"和諧"起來的呢?linux把目錄也看成一種文件,裡面記錄著文件名與索引節點號的對應關系。比如在ext3文件系統中,如果文件是一個目錄,那麼它的內容就是一系列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 */
};
舉個例子,比如要打開/home/test/hello.c。首先,找到‘/’,讀入其內容,找到名為"home"的文件的索引節點號,打開/home這個"文件",讀入內容,找到名為 "test" 的的文件的索引節點號,同理,再打開文件"/home/test",找到找到名為"hello.c”的文件的索引節點號,最後就得到/home/test/hello.c了。這就是path_walk()函數的原理。
其中,根據一個文件夾的inode,和一個文件名來獲取該文件的inode結構的函數,就叫lookup,它是inode_operations裡面的函數。
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
lookup,顧名思義,就是查找,比如查查在test這個文件夾下,有沒有叫hello.c的文件,有的話,就從存儲介質中讀取其inode結構。並用dentry->d_inode指向它。所以,我們只要知道了文件的路徑和名字,總可以從根目錄開始,一層一層的往下走,定位到某一個文件。
superblock與vfsmount
接下來還要介紹兩個數據結構,superblock和vfsmount。super_block結構是從所有具體的文件系統所抽象出來的一個結構,每一個文件系統實例都會有一對應super_block結構。比如每一個ext2的分區就有一個super_block結構,它記錄了該文件系統實例(分區)的某些描述性的信息,比如該文件系統實例的文件系統類型,有多大,磁盤上每一塊的大小,
還有就是super_operations。它與inode,dentry一樣,只是某些內容在內存中的映像。就ext2文件系統而言,設備上的超級塊為ext2_super_block。由於sysfs是虛擬的文件系統,獨一無二, 並且只能被mount一次,sysfs的super_block結構是sysfs_sb。sysfs_sb也是動態的從內存中生成的。
還有要提一下super_operations,它也算是VFS的一個接口。實現一個文件系統file_operations, dentry_operations, inode_operations, super_operations這四個結構都要實現。
把一個設備安裝到一個目錄節點時要用一個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 */
..........
}
對於某個文件系統實例,內存中super_block和vfsmount都是唯一的。比如,我們將某個掛載硬盤分區mount -t vfat /dev/hda2 /mnt/d。實際上就是新建一個vfsmount結構作為連接件,vfsmount->mnt_sb = /dev/hda2的超級塊結構;vfsmount->mntroot = /dev/hda2的"根"目錄的dentry;vfsmount->mnt_mountpoint = /mnt/d的dentry; vfsmount->mnt_parent
= /mnt/d所屬的文件系統的vfsmount。並且把這個新建的vfsmount連入一個全局的hash表mount_hashtable中。
從而我們就可以從總根’/’開始,沿著dentry往下找。假如碰到一個某個目錄的dentry是被mount了的,那麼我們就從mount_hashtable表中去尋找相應的vfsmount結構 (函數是lookup_mnt())。然後我們得到vfsmount ->mnt_root,就可以找到mount在該目錄的文件系統的"根"dentry結構。然後又繼續往下走,就可以暢通無阻了。
關於path_walk()的代碼我就不貼了,太長了。其實懂了原理後再去看,很簡單,跟看故事會差不多。我當年就是看完這個函數後,信心倍增阿。pathwalk,不管前面是高速公路,或是泥濘的鄉間小路,我們都要走到底。
Copyright © Linux教程網 All Rights Reserved