摘要:我們對於ext2/ext3檔案系統的了解大多來自作業系統的課本或者《understanding linux kernel》這本書,但是最近做了乙個專案,需要根據檔案的inode結點號找到inode本身。因此需要對ext2/ext3檔案系統做深入的理解。在做的過程中才發現,原來書上講的理論和現實的差距太大了。可能是因為書比較早,或者書上只是講了乙個概念模型,以至從實際工程的角度來看,課本上有好多的東西簡直可以說是錯誤的。本文就把在工程中發現的問題和ext2/ext3檔案系統的真相展示出來。
第一章:經典而又經典的圖其實是錯的
首先說明
ext3
檔案系統和
ext2
檔案系統的區別。
ext3
檔案系統是帶有日誌的
ext2
檔案系統,在設計時就秉承盡可能與
ext2
檔案系統相容的理念,因此他的檔案系統資料結構與
ext2
檔案系統的本質上是相同的。事實上可以把乙個
ext3
檔案系統解除安裝後做為
ext2
檔案系統重新安裝。反之也可以把建立日誌的
ext2
檔案系統做為
ext3
檔案系統掛載。
ext2
檔案系統的磁碟資料結構如下圖所示:
除了硬碟分割槽中的第一塊作為引導塊所保留,不受
ext3
檔案系統管理以外
,其餘部分分成塊組(
blockgroup
),每個快組的分布下圖所示,由於核心盡可能把屬於乙個檔案的資料塊存放在同一塊中,所以組塊減少了檔案碎片。塊組中的每塊包含下列資訊: ÿ
超級塊:檔案系統超級塊的乙個拷貝 ÿ
組描述符:一組塊組描述符的拷貝 ÿ
資料塊點陣圖:乙個資料塊點陣圖 ÿ
索引節點位圖:一組索引節點 ÿ
索引節點表:乙個索引節點位圖 ÿ
資料塊:存放檔案資料
其中超級塊描述整個檔案系統的資訊,包括此檔案系統共有多少個塊組,每個塊組包含多少個塊,包含的結點的個數,每個結點的大小。
組描述符表描述的是每個組的情況,每個組有乙個組描述符,大小為
32位元組。檔案系統中所有的組描述符放在一起構成了組描述符表。
組描述符表之後是資料塊點陣圖和索引結點點陣圖各佔乙個塊。隨後就是這個組的索引結點表,每個索引結點占用
128個位元組。
塊組的大小是由資料塊點陣圖決定的。假設檔案系統的資料塊大小為
b位元組(可以配置為1k,
2k,4k),則每個資料塊點陣圖可以描述的磁碟塊大小為
b * 8
,即8 * b * b
個位元組大小。通常情況下塊大小為
4k,則乙個塊組包含
32k個物理塊。需要說明是這
32k個塊並不全是資料塊,而是包含元資料塊和資料塊的總和。這樣看似備份的元資料浪費了資料塊,但這種浪費換來的是查詢效能上的提公升。
塊組大小確定之後,整個系統中的塊組數就可以確定了,即磁碟總容量
/每個塊組的容量。
確定塊組的重要的意義在於確定
inode
號。在整個檔案系統中
inode
號是統一編址的,因此可以根據
inode
號確定這個
inode
所在的組號以及組內的偏移,進而找到這個
inode。
根據上圖,
inode
結點的位址的位元組偏移應該按如下的方法計算:
inode
位址= ((inode_no / inode_per_group) * block_per_group + (1 + n + 1 +
1)) * block_size + ( inode_no % inode_per_group ) * inode_size + 1024
其中inode_no
為結點號,
inode_per_group
為每個塊組含有多少個結點,
block_per_group
為每個塊組的塊的個數,
(1 + n + 1 +1)
表示乙個超級塊,乙個資料塊點陣圖,乙個索引結點位圖,
n表示塊組的個數,最後加上引導塊占用的
1k個位元組。
但是實際的情況是這個公式是錯誤的,按照這個公式不可能讀到索引結點。
第二章:尋找inode結點
產生錯誤的原因在於課本上所講的資料結構是錯誤的,或者說只是乙個邏輯上的模型,與實際在物理磁碟上存放的資料結構有很大的差別。首先看一張真正的磁碟資料結構圖:
對比和上一張圖的不同,真實的磁碟布局中有三種塊組,一種是塊組
0,一種備份塊組,一種是普通塊組。塊組0
即包含引導塊的塊組,通常系統使用元資料資訊都是從這個塊組中讀取,只有當這個塊組中的元資料發生錯誤時才會從備份的塊組中恢復。
由此產生了和課本的衝突,並不是所有的塊組都會備份乙份元資料資訊,只有部分塊組會備份。但是哪些塊組會備份呢?只有當塊組號是3,
5,7的冪的塊組才會備份元資料,其他塊組則是做為普通塊組只存放資料,不備份元資料。
和課本的另乙個衝突,引導塊佔據
1k的空間,他雖然不被檔案系統管理,但他確實佔據了磁碟
0塊組的第乙個塊。所以教科書上的畫法是不妥當的,或者說教科書只是畫出了一種邏輯的磁碟結構,並不反應現實。在
0塊組的第乙個塊中,引導塊和超級塊各佔了
1k的空間,留下了
2k的空閒。而在其他的備份塊組中則沒有引導塊的備份,只是在第乙個塊中備份了乙個超級塊。
和課本的下乙個衝突,在實際中出現了乙個課本上沒有提到過的區域,
reserve gdt,
而且還是乙個占用了不少塊的區域。這個區域是為了以後擴容用的。當以後為檔案系統擴容時,可能人增加新的塊組,塊組描述符表也會相應增加,這個
reserve gdt
就是為那時使用的。這個區域占用多少個塊我還沒有找到計算方法,但是在
super block
結構中有乙個域指示了這個區域占用的塊數,可以直接讀出。
至此,我們得到計算
inode
結點位元組偏移的真正方法:
inode_address = ((inode_no / inode_per_group) * block_per_group + (1+n+n+1+1) * is_backup_group ) * block_size + (inode_no % inode_per_group) * inode_size
這就是真實的
ext3
檔案系統的磁碟布局。到此我們可以拿到
inode
,可以進行查詢操作了。
第三章:問題才剛剛開始
第乙個問題:inode結點號真的是對的嗎?
每個檔案有乙個
inode
結點,這個結點對應乙個
inode
結點號。這個結點號可以由
ls –i
命令得到,也可以用
debugfs
工具得到。但是這個
inode
結點號真的就是在磁碟物理空間上的結點順序號嗎
? 看了核心中相應的一段**才知道,這個
inode
結點號是不能直接拿來用的,必須減
1才能用。減
1是因為沒有
0號結點,我們拿到的結點號是從
1開始計數的。
第二個問題:讀寫大檔案
第二個問題是當把裝置做為檔案開啟時,可能會因為裝置過大導致檔案無法支援,但是這時做的
lseek
,read
操作會全部正確返回,但這時操作的結果是錯誤的,因為大的資料被截斷了。解決方法是使用
lseek64,
或者_llseek
。
EXT2 EXT3檔案系統(二)
整理自 鳥哥的linux私房菜 整理者 華科小濤 接ext2 ext3檔案系統 一 2.3 superblock 超級塊 2.4 file system description 檔案系統描述說明 這個區段可以描述每個block group的開始與結束的block號碼,以及說明每個區段分別介於哪乙個b...
EXT2 EXT3檔案系統(一)
華科小濤 檔案系統 是一種儲存和組織計算機資料的方法,它使得對其訪問和查詢變得容易,檔案系統使用檔案和樹形目錄的抽象邏輯概念代替了硬碟和光碟等物理裝置使用資料塊的概念,使用者使用檔案系統來儲存資料不必關心資料實際儲存在硬碟 或者光碟 的位址為多少的資料塊上,只需要記住這個檔案的所屬目錄和檔名。在寫入...
深入理解ext4檔案系統
學習ext4的檔案系統,發現了大神的部落格,寫的非常詳細,通俗易懂,膜拜中.ext4 01 磁碟布局 block分析 ext4 02磁碟布局 group分析 ext4 03 磁碟布局 flexible group分析 ext4 04 磁碟布局 meta block groups ext4 05 磁碟...