當安裝
ext2
檔案系統時(執行諸如
mount -t ext2 /dev/sda2 /mnt/test
的命令),存放在
ext2
分割槽的磁碟資料結構中的大部分資訊將被拷貝到
ram中,從而使核心避免了後來的很多讀操作。那麼一些資料結構如何經常更新呢?因為所有的
ext2
磁碟資料結構都存放在
ext2
磁碟分割槽的塊中,因此,核心利用頁快取記憶體來保持它們最新。
前面談到,安裝
ext2
檔案系統時,最終會呼叫
ext2_fill_super()
函式來為資料結構分配空間,並寫入從磁碟讀取的資料。該函式首先用
kmalloc
分配乙個
ext2_sb_info
描述符,將其位址賦給當做引數傳遞進來的超級塊
super_block
的s_fs_info
字段。隨後通過
__bread()
在緩衝區頁中分配乙個緩衝區和緩衝區首部,這個函式屬於也快取記憶體的範圍,詳細介紹請到部落格「在頁快取記憶體中搜尋塊」
。然後從磁碟讀入超級塊存放在緩衝區中。在「在頁快取記憶體中搜尋塊」一博我們討論過,如果乙個塊已在頁快取記憶體的緩衝區頁而且是最新的,那麼無需再分配。將緩衝區首部位址存放在
ext2
超級塊物件
sbi的
s_sbh
字段,之後再用
kmalloc
分配乙個陣列用於存放緩衝區首部指標,每個組描述符乙個,把該陣列位址存放在
ext2_sb_info
的s_group_desc
字段。這樣,就可以通過重複呼叫
__bread()
分配緩衝區,從磁碟讀人包含
ext2
組描述符的塊。把緩衝區首部位址存放在上一步得到的
s_group_desc
陣列中。
最後安裝
sb->s_op
,sb->s_export_op
,超級塊增強屬性。因為準備為根目錄分配乙個索引節點和目錄項物件,必須把
s_op
欄位為超級塊建立好,從而能夠從磁碟讀入根索引節點物件:
sb->s_op = &ext2_sops;
sb->s_export_op = &ext2_export_ops;
sb->s_xattr = ext2_xattr_handlers;
root = iget(sb, ext2_root_ino);
sb->s_root = d_alloc_root(root);
注意,ext2_root_ino是2
,也就是它的根節點,位於第乙個塊組的第三個位置上。
sb->s_op
被賦值成了
ext2_sops
來自fs/ext2/super.c
:static struct super_operations ext2_sops = ;
很顯然,
ext2_fill super()
函式返回後,有很多關鍵的
ext2
磁碟資料結構的內容都儲存在記憶體裡了,例如
ext2_super_block
、塊裝置的索引節點等,只有當
ext2
檔案系統解除安裝時才會被釋放。當核心必須修改
ext2
超級塊的字段時,它只要把新值寫入相應緩衝區內的相應位置然後將該緩衝區標記為臟即可,有了頁快取記憶體事情就是這麼簡單!
以上內容僅簡單介紹一下該函式的一些關鍵步驟。該函式的詳細分析請檢視部落格「
ext2
的超級塊物件」
,並結合我們這裡給出的資料結構圖進行分析:
要弄清第二擴充套件檔案系統
ext2
層的處理,除了
ext2
超級快物件,還要弄懂乙個
ext2
索引節點物件。我們在上一節看到
ext2_fill_super
函式中,當初始化超級快後,還有一步是呼叫
iget
將索引節點號為
ext2_root_ino
(一般為
2)的索引節點分配給該
ext2
磁碟分割槽的載入目錄,也就是根目錄項。
static inline struct inode *iget(struct super_block *sb, unsigned long ino)
return inode;
}看到ext2_sops
全域性變數我們得知,
ext2_read_inode
就是ext2
超級塊的
s_op->read_inode
具體實現函式,該函式會呼叫
ext2_get_inode
函式,從乙個頁快取記憶體中讀入乙個磁碟索引節點結構
ext2_inode
,然後初始化
vfs的
inode
。當然,這個根目錄不是普通檔案,而是乙個目錄檔案,所以我們後面章節再來深入研究,這裡只介紹其中最重要的初始化**段,如下:
struct inode *ext2_read_inode(struct inode *ino)
else if (test_opt(inode->i_sb, nobh)) else
} else if (s_isdir(inode->i_mode)) else if (s_islnk(inode->i_mode))
} else
……}我們看到根目錄的
inode
結構的i_op 、和
i_fop
欄位被賦值了。先來看一下
i_fop
被初始化成了
ext2_file_operations
全域性變數:
struct file_operations ext2_file_operations = ;
i_op
也被初始化成了
ext2_file_inode_operations
全域性變數:
struct inode_operations ext2_file_inode_operations = ;
也被初始化成了
ext2_aops
全域性變數:
const struct address_space_operations ext2_aops = ;
ext2讀取並產生間接塊和資料塊
讀取並產生資料塊和間接塊 在學習頁快取的時候,我們看到這樣一張圖 ext2 get branch跟蹤這個路徑,最終到達乙個資料塊。函式中呼叫sb bread 相繼讀取各個間接塊。每個塊的資料和從路徑得知的偏移量,可用於找到指向下乙個間接塊的指標。一直重複,直到到達乙個資料塊,這時函式返回null,表...
Ext2的索引節點
摘自 ext2的索引節點 ext2 和unix類的檔案系統一樣,使用索引節點來記錄檔案資訊。每乙個普通檔案和目錄都有唯一的索引節點與之對應,索引節點中含有檔案或目錄的重要資訊。當你要訪問乙個檔案或目錄時,通過檔案或目錄名首先找到與之對應的索引節點,然後通過索引節點得到檔案或目錄的資訊及磁碟上的具體的...
ext2檔案系統
ext2磁碟結構 ext2分割槽和ext2分組的分布圖 下圖是借用其他部落格的 塊組中的每個塊包含的資訊 超級快 1個塊 描述該分割槽中的整個檔案系統的資訊,包括有多少個快組,每個快組有多少個塊,多少個索引節點等。組描述符塊 n塊 塊點陣圖 1塊 索引節點位圖 1塊 索引節點 n塊 資料塊 n塊 塊...