1. 程式人生 > >hello_world-3.1之增加操作函式fops(一)概念介紹

hello_world-3.1之增加操作函式fops(一)概念介紹

      所有的dentry用d_parent和d_child連線起來,就形成了我們熟悉的樹狀結構。

inode代表的是物理意義上的檔案,通過inode可以得到一個數組,這個陣列記錄了檔案內容的位置,如該檔案位於硬碟的第3,8,10塊,那麼這個陣列的內容就是3,8,10。其索引節點號inode->i_ino,在同一個檔案系統中是唯一的,核心只要根據i_ino,就可以計算出它對應的inode在介質上的位置。就硬碟來說,根據i_ino就可以計算出它對應的inode屬於哪個塊(block),從而找到相應的inode結構。但僅僅用inode還是無法描述出所有的檔案系統,對於某一種特定的檔案系統而言,比如ext3,在記憶體中用ext3_inode_info描述。他是一個包含inode的"容器"。

dentry和inode終究都是在記憶體中的,它們的原始資訊必須要有一個載體。否則斷電之後豈不是玩完了?且聽我慢慢道來。

檔案可以分為磁碟檔案,裝置檔案,和特殊檔案三種。

磁碟檔案
就磁碟檔案而言,dentry和inode的載體在儲存介質(磁碟)上。對於像ext3這樣的磁碟檔案來說,儲存介質中的目錄項和索引節點載體如下,
struct ext3_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Creation time */
__le32 i_mtime; /* Modification time */

__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
......
__le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
......
}
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 */
};

le32 i block[EXT2 N BLOCKS];/* Pointers to blocks */
i_block陣列指示了檔案的內容所存放的地點(在硬碟上的位置)。

ext3_inode是放在索引節點區,而ext3_dir_entry_2是以檔案內容的形式存放在資料區。我們只要知道了ino,由於ext3_inode大小已知,我們就可以計算出ext3_inode在索引節點區的位置( ino * sizeof(ext3_inode) ),而得到了ext3_inode,我們根據i_block就可以知道這個檔案的資料存放的地點。將磁碟上ext3_inode的內容讀入到ext3_inode_info中的函式是ext3_read_inode()。以一個有100 block的硬碟為例,一個檔案系統的組織布局大致如下圖。點陣圖區中的每一位表示每一個相應的物件有沒有被使用。


特殊檔案
特殊檔案在記憶體中有inode和dentry資料結構,但是不一定在儲存介質上有"索引節點",它斷電之後的確就玩完了,所以不需要什麼載體。當從一個特殊檔案讀時,所讀出的資料是由系統內部按一定的規則臨時生成的,或從記憶體中收集,加工出來的。sysfs裡面就是典型的特殊檔案。它儲存的資訊都是由系統動態的生成的,它動態的包含了整個機器的硬體資源情況。從sysfs讀寫就相當於向kobject層次結構提取資料。

還請注意, 我們談到目錄項和索引節點時,有兩種含義。一種是在儲存介質(硬碟)中的(如ext3_inode),一種是在記憶體中的,後者是根據在前者生成的。記憶體中的表示就是dentry和inode,它是VFS中的一層,不管什麼樣的檔案系統,最後在記憶體中描述它的都是dentry和inode結構。我們使用不同的檔案系統,就是將它們各自的檔案資訊都抽象到dentry和inode中去。這樣對於高層來說,我們就可以不關心底層的實現,我們使用的都是一系列標準的函式呼叫。這就是VFS的精髓,實際上就是面向物件。

我們在程序中開啟一個檔案F,實際上就是要在記憶體中建立F的dentry,和inode結構,並讓它們與程序結構聯絡來,把VFS中定義的介面給接起來。我們來看一看這個經典的圖。這張圖之於檔案系統,就像每天愛你多一些之於張學友,番茄炒蛋之於復旦南區食堂,刻骨銘心。