深入剖析Linux文件系統(tǒng)之ext2路徑名查找(超詳細(xì)~)
本文以ext2文件系統(tǒng)為例來剖析一個真實的文件系統(tǒng)如何查找文件,這對于深入理解文件系統(tǒng)至關(guān)重要。
1.準(zhǔn)備文件系統(tǒng)鏡像
所用工具:dd、mkfs.ext2、hexdump、dumpe2fs、mount等工具
1)制作100k大小鏡像文件
2)格式化為ext2文件系統(tǒng)格式
3)查看文件系統(tǒng)信息
這實際是是讀取文件系統(tǒng)的超級塊和塊組描述符信息。我們可以看的創(chuàng)建的文件系統(tǒng)的總體信息:
Filesystem magic number:0xEF53 表示為ext2文件系統(tǒng)Inode count: 16 表示文件系統(tǒng)inode個數(shù)為16Block count: 100 表示文件系統(tǒng)塊個數(shù)為100 Free blocks: 79 表示文件系統(tǒng)空閑塊個數(shù)為79Free inodes: 5 表示文件系統(tǒng)空閑inode個數(shù)為5 First block: 1 第一個數(shù)據(jù)塊編號為1(編號0保留為引導(dǎo)塊) Block size: 1024 文件系統(tǒng)塊大小為1kBlocks per group: 8192 每個塊組8192個塊Inodes per group: 16 每個塊組個inode Inode blocks per group: 2 每個塊組2個inode塊 First inode: 11 分配的第一個inode號為11(除根inode外,根inode號為2)Inode size: 128 inode大小為128字節(jié)塊組的信息(這里只有一個塊組) 1 - 99號 超級塊塊編號為 1 塊組描述符塊編號為 2 塊位圖塊編號為 3 inode位圖塊編號為 4
inode表位于5和6塊
79 個可用 塊,5 個可用inode,2 個目錄 (一個為根目錄一個為lost+found,存放壞塊) 可用塊數(shù):21-99 可用inode數(shù):12-16
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ?


4)掛載文件系統(tǒng)并創(chuàng)建文件
可以發(fā)現(xiàn)有三個目錄:
實際上是根目錄的數(shù)據(jù)塊的內(nèi)容(包含各個目錄項)。
下面我們來創(chuàng)建一個目錄,目錄下創(chuàng)建文件:
現(xiàn)在目錄樹是這樣的:
后面我們會通過解析文件系統(tǒng)鏡像來觀察如何查找 /dir/test.txt 文件的
現(xiàn)在關(guān)注一下相關(guān)的索引節(jié)點:
可以發(fā)現(xiàn) /dir目錄下:當(dāng)前工作目錄下索引節(jié)點為12(dir目錄的),上一級目錄的索引節(jié)點為2(根目錄),test.txt文件的所有節(jié)點為13。記住這幾個索引節(jié)點后面我們會通過解析文件系統(tǒng)鏡像來獲得。
2.解析文件系統(tǒng)鏡像
1)dump文件系統(tǒng)鏡像
根據(jù)之前dumpe2fs的信息我們知道:
鏡像文件中(均為16進(jìn)制顯示) 00000000 開始的1k大小 保留的引導(dǎo)塊 塊1 00000400 開始的1k大小 保存磁盤的超級塊 (dumpe2fs的部分信息從這里獲得) 塊2 00000800 開始的1k大小 保存塊組描述符 (dumpe2fs的部分信息從這里獲得) 塊3 00000c00 開始的1k大小 保存塊位圖 塊4 00001000 開始的1k大小 保存 Inode 位圖 塊5 塊6 00001400 開始的2k大小 保存 Inode表 剩下的為數(shù)據(jù)塊
磁盤中的文件系統(tǒng)對象結(jié)構(gòu)在內(nèi)核如下文件定義:
大家可以對照磁盤鏡像文件和磁盤數(shù)據(jù)結(jié)構(gòu)定義來解析出文件系統(tǒng)的超級塊和塊組描述符信息(可以發(fā)現(xiàn)和dumpe2fs工具顯示的是一致的,例如鏡像文件00000400 處四字節(jié)為10 00 00 00 是小端存儲,所以為0x00000010=16);
3.路徑名查找
下面開始我們的重頭戲:查找文件系統(tǒng)中的 /dir/test.txt 文件。
我們知道,使用文件系統(tǒng)給我最直觀也是最大的好處是:用戶可以通過一個路徑名來訪問文件,那么一個文件系統(tǒng)究竟如何來找到我們所需要的文件呢?下面我們詳細(xì)來看ext2文件系統(tǒng)如何查找指定的文件的?(實際的內(nèi)核中路徑名查找比較復(fù)雜,考慮很多情況,如dentry cache查找、解析軟鏈接文件、上級目錄、掛載點等,當(dāng)然如果目錄分量是掛載點就會步進(jìn)到相應(yīng)文件系統(tǒng)的根目錄,后面文件系統(tǒng)掛載專題會講解,這里以簡單的路徑解析來讓大家有個深刻的認(rèn)識)。
1)查找根目錄
萬事開頭難,對于訪問一個目錄上掛載的文件系統(tǒng),內(nèi)核路徑名查找會判斷并找到掛載的文件系統(tǒng)的根目錄,這個過程在文件系統(tǒng)掛載的時候,會從磁盤上讀取并在內(nèi)存構(gòu)建超級塊實例,然后進(jìn)行的最重要的一步是讀取文件系統(tǒng)的根inode:
簡述ext2通過inode號找到并讀取磁盤inode核心算法:
根據(jù)inode號計算出所在的塊組block_group
根據(jù)inode號計算出塊組中的inode表中的字節(jié)偏移offset
根據(jù)inode號計算出磁盤inode在文件系統(tǒng)中的塊號block
根據(jù)塊號block 通過sb_bread讀取緩沖區(qū)塊到內(nèi)存
根據(jù)inode表中的字節(jié)偏移offset 計算出 磁盤inode在塊中偏移
通過讀取的緩沖區(qū)和磁盤inode在塊中偏移 最終返回磁盤inode結(jié)構(gòu)
我們已知:
每個塊組inode個數(shù):EXT2_INODES_PER_GROUP(sb) = 16 磁盤inode大?。篍XT2_INODE_SIZE(sb) = 128 塊大小的bit表示:EXT2_BLOCK_SIZE_BITS(sb) = 10
所以計算根inode塊號:
所以:根inode所在的鏡像文件中偏移為:5 * 0x400 + 0x80 = 0x1400 + 0x80 = 0x1480
對照ext2文件系統(tǒng)磁盤inode結(jié)構(gòu),可知i_block為磁盤inode結(jié)構(gòu)的偏移40B處,內(nèi)容即為0x07(ext2通過i_block來查找文件在磁盤中的位置)。
于是我們知道,根目錄數(shù)據(jù)塊的塊號 為0x7(鏡像中字節(jié)偏移為 0x400 * 7= 1c00),這個數(shù)據(jù)塊中保存的是根目錄中包含的所有目錄和文件的目錄項(我們知道這里為"."、".."、"dir"、"lost+found"四個目錄項)。
根據(jù)目錄項ext2_dir_entry_2 結(jié)構(gòu)我們可以查詢到文件名為dir的目錄項,從而獲取dir目錄的inode號,為0x0c(和我們之前通ls -lai顯示的dir目錄inode號12是一致)。
2)查找dir目錄
和上面查詢根inode一樣的原理,計算過程如下:
所以:dir目錄inode所在的鏡像文件中字節(jié)偏移為:6 * 0x400 + 0x180 = 0x1800 + 0x180 = 0x1980
對照ext2文件系統(tǒng)磁盤inode結(jié)構(gòu),可知i_block為磁盤inode結(jié)構(gòu)的偏移40B處,內(nèi)容即為0x63。
于是我們知道,dir目錄數(shù)據(jù)塊的塊號 為0x63(偏移為 0x400 * 0x63= 0x18c00),這個數(shù)據(jù)塊中保存的是dir目錄中包含的所有目錄和文件的目錄項(我們知道這里為"."、".."、"test.txt"三個目錄項)。
對照目錄項ext2_dir_entry_2 結(jié)構(gòu),查找文件名為test.txt的inode號,即為0x0d(和我們之前通ls -lai顯示的dir目錄inode號13是一致)。
于是我們知道,test.txt文件的inode號為0x0d(13)。
3)查找test.txt文件
和上面查詢根inode一樣的原理,計算過程如下:
所以:test.txt文件inode所在的鏡像文件中偏移為:= 6 * 0x400 + 0x200 = 0x1800 + 0x200 = 0x1a00
對照ext2文件系統(tǒng)磁盤inode結(jié)構(gòu),可知i_block為磁盤inode結(jié)構(gòu)的偏移40B處,內(nèi)容即為0x15。
于是我們知道,test.txt文件數(shù)據(jù)塊的塊號 為0x15(偏移為0x15 * 0x400 = 0x5400)。
最終可以看到文件數(shù)據(jù)為"hello"。
4)查找過程圖解
以下為 dir/test.txt查找過程:
已知根目錄inode號(ext2為2) -> 查找根目錄磁盤inode(文件系統(tǒng)掛載時查找) -> 查找根目錄的數(shù)據(jù)塊 -> 查找dir目錄的目錄項找到其inode號 (為12) -> 查找dir目錄的磁盤inode -> 查找dir目錄的數(shù)據(jù)塊 -> 查找test.txt文件的inode號(為13) -> 查找test.txt文件的磁盤inode -> 查找test.txt文件的數(shù)據(jù)塊
下面為查找圖解:

4.總結(jié)
對于ext2文件系統(tǒng),路徑名查找中,實際上是解析路徑名的各個分量,查找每個分量的目錄項,然后通過目錄項找到inode號,通過inode號找到對應(yīng)的磁盤inode,然后通過磁盤inode獲得目錄/文件的數(shù)據(jù)塊, 最終查找到對應(yīng)目錄/文件的磁盤inode,而磁盤inode的i_block中保存著文件的邏輯塊號和磁盤的邏輯塊號映射關(guān)系,讀寫文件時就可以訪問到整個文件。
