深入理解ext4

 文件系統是操作系統的一個重要組成部分,也有着舉足輕重的地位。本系列文章主要講述了linux ext4文件系統的一些實現原理。筆者參考了2.6.32.60的內核源代碼。在寫這篇的文章時,最新的內核已經去到了3.7.9。

ext4是替代ext2/3Linux文件系統。從2.6.28版本開始,被正式認定進入穩定(stable)。本文主要介紹ext4文件系統在硬盤層面上的存儲結構及原理。

 

讀者對象:對Linux有一定基礎,希望瞭解ext4底層原理,和它與ext2/3系統區別。

 

關鍵詞彙

先回顧幾個基本的概念,如果不是特別清楚下面幾個概念的話,可以去google一下。

inode:索引節點

superblock:超級塊

block:文件系統塊

block group:文件系統塊組

disk block:磁盤塊(512字節)

block device:塊設備

VFS:虛擬文件系統

EXT4存儲結構

假如把整個超級塊比如一本書,那麼文件系統的工作就是把要記錄的內容,按頁碼,行段記錄在這本書裏。這當然也包括書的目錄了。我們使用dumpe2fs工具輸出:

 

Reserved GDT blocks:      609

Blocks per group:         32768

Fragments per group:      32768

Inodes per group:         8128

Inode blocks per group:   508

Flex block group size:    16

Filesystem created:       Mon May 14 13:30:51 2012

Last mount time:          Sun Jan  6 18:51:16 2013

Last write time:          Sun Jan  6 18:51:16 2013

Mount count:              282

Maximum mount count:      -1

Last checked:             Mon May 14 13:30:51 2012

Check interval:           0 (<none>)

Lifetime writes:          20 GB

Reserved blocks uid:      0 (user root)

Reserved blocks gid:      0 (group root)

First inode:              11

Inode size:               256

Required extra isize:     28

Desired extra isize:      28

Journal inode:            8

 

首先,映入眼簾的是該超級塊的相關重要參數,比如inode大小,塊組含塊數,塊組inode數目等等。這些數據是存在ext4_super_blockext4_sb_info這兩個結構體中,定義在ext4.h頭文件裏,它們不是本篇重要討論的內容。我們只需要知道它們是存放一些超級塊信息的結構體即可。

接下來,可以看到ext4硬盤上的存儲結構:

Group 0: (Blocks 0-32767) [ITABLE_ZEROED]

  Checksum 0x7cf3, unused inodes 0

  Primary superblock at 0, Group descriptors at 1-2

  Reserved GDT blocks at 3-611

  Block bitmap at 612 (+612), Inode bitmap at 628 (+628)

  Inode table at 644-1151 (+644)

  2720 free blocks, 0 free inodes, 1383 directories

  Free blocks: 8888-8959, 9068, 9071-9135, 9144-9175, 9200-9207, 9213-9214, 9279, 9700-10120, 11823-11964, 12213-12870, 12879-13043, 13139-13254, 18432-19021, 22748-22975, 32549-32767

  Free inodes:

 

這是塊組0的情況,它表明塊組0由塊號爲0-3276732768個塊組成,超級塊基本信息存在塊0,塊組描述符在塊1-2,預留的塊組描述符表在塊3-611,塊位圖在塊612中,inode位圖在塊628中,Inode表在塊644-1151中,空閒的塊有很多,空閒的inode沒了。

接下來,我們將重點分析這句廢話中每個詞的含義

        超級塊基本信息:

                  我們在前面已經講過了。顧名思義,不多解釋。

         塊組描述符

                  在內核中就是結構體ext4_group_desc,它包括的內容爲:塊位圖塊號,inode位圖塊號,inode表塊號,空閒塊計數,自由塊計數等等。

         預留的塊組描述符表

                  爲以後要使用所留下來的空間。

         塊位圖

                  這個就是一個塊使用情況記錄表。記錄哪些塊使用,哪些塊未使用。它的原理就是對整個塊組中0-32767這總共32768個塊中作一個映射。根據一個bytes8個位00000000,一個塊有4096bytes也就是有4096*8=32768個位,這32768個位剛好對應了塊組中32768的塊。如果第N個塊被使用了則標記第N位爲1,否則爲0

         inode位圖

                  和上面的塊位圖一樣,這個是inode的使用情況記錄表。由超級塊基本信息可以看到每個塊組有8128inode,這裏對inode的映射原理和塊位圖也是一樣,只不過         沒有用滿一個塊。

         inode

                  inode表就是具體存放inode信息的地方。在ext4中,inode的大小爲256字節(ext2/3中僅有它的一半,128字節),一個塊可以存放16inode,由於一個塊組有8128          inode,總共需要8128/16=508個塊存放inode表。這個值可以在超級塊基本信息中的Inode blocks per group中看到。

講完了這些詞的含義,我們對group 0有了初步的瞭解。那麼group 1呢?

Group 1: (Blocks 32768-65535) [ITABLE_ZEROED]

  Checksum 0xbb99, unused inodes 0

  Backup superblock at 32768, Group descriptors at 32769-32770

  Reserved GDT blocks at 32771-33379

  Block bitmap at 613 (+4294935141), Inode bitmap at 629 (+4294935157)

  Inode table at 1152-1659 (+4294935680)

  598 free blocks, 0 free inodes, 648 directories

  Free blocks: 33424-33439, 33442-33443, 33564-33627, 33644-33647, 33652-33663, 33725-33871, 33878-33931, 33934-33973, 33976-33983, 34046-34047, 34176-34303, 36008, 36015, 36019, 36412, 40299-40415

  Free inodes:

 

我們看到group 1 中,primary superblock 變爲了backup superblock,由於超級塊基本信息對於文件系統至關重要,爲了系統的健壯性,ext文件系統在每個塊組中都進行了備份。ext4考慮到在每個塊組中都備份有點多餘,尤其是組描述符表所以就僅在塊號以357爲冪的塊組上進行備份。

用個表格表示超級塊中塊組的結構:

ext4 超級塊

塊組描述符

Reserved GDT Blocks

數據塊位圖

Inode位圖

inode 表

數據塊

1 block

若干blocks

若干 blocks

1 block

1 block

若干

好多好多塊

                                                                                                                                                    

inode

Purpose

0

Doesn't exist; there is no inode 0.

1

List of defective blocks.

2

Root directory.

3

ACL index.

4

ACL data.

5

Boot loader.

6

Undelete directory.

7

Reserved group descriptors inode.

8

Journal inode.

11

First non-reserved inode. Usually this is the lost+found directory.

 

塊尋址

ext4的塊尋址已經改爲48位。這種設計改動是爲了支持更大的文件系統大小。EXT4使用了區段(extents)這個概念,取代了過去早期UNIX文件系統中(ext2/3)中低效的非直接塊映射機制。區段和NTFS上的cluster有點類似,它們都是選定了一個特定的塊地址並把數個塊組合一個區間。一個文件如果是碎片化的,那麼就意味它着擁有多個區段,ext4會盡它自己的努力保持文件連續。

 

這種新的塊尋址策略導致了先前工具的大部分問題。舉個列子:

 

[root@localhost Desktop]# stat math.c

  File: `math.c'

  Size: 1477               Blocks: 8          IO Block: 4096   regular file

Device: fd00h/64768d     Inode:420402      Links: 1

Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Access: 2013-01-05 15:07:11.815541582 +0800

Modify: 2012-08-20 13:40:02.496797954 +0800

Change: 2012-12-30 11:28:54.751357610 +0800

 

 

由上面得到文件math.cInode號爲420402

[root@localhost Desktop]# istat /dev/mapper/VolGroup-lv_root 420402

inode: 420402

Allocated

Group: 51

Generation Id: 1062005310

uid / gid: 0 / 0

mode: rrw-r--r--

Flags:

size: 1477

num of links: 1

 

Inode Times:

Accessed:         2013-01-05 15:07:11 (CST)

File Modified:   2012-08-20 13:40:02 (CST)

Inode Modified:        2012-12-30 11:28:54 (CST)

 

Direct Blocks:

127754

 

 

由上面的命令結果可以看到,Inode位於節點上塊組51上,留意上面命令最下面有Direct Blocks這一行,這一行寫着127754。在ext4的文件系統中,由於direct block映射的塊尋址機制被取代,而採取的是extent區段樹的塊尋址。這個地方的值基本上是無效的。127754這個值十六進制表示爲0x1f30a,我們在稍後的討論這個值的來源。

我們知道了math.c這個文件的inode號碼爲420402,那麼怎樣知道它數據塊是拿一個呢?

由前面的內容我們知道,每個塊可以存16inode,那麼420402則在第420402/16=26275.125個塊中,也就是位於第26275個塊的第二個位置。每個塊組有508inode塊,那麼26725/508=51.72可以得知,位於塊組51號之中,這個值可以在我們之前istat中可以驗證。

那麼具體是51塊組中的哪個塊呢?我們先確定這個inode塊是在塊組中的第幾個塊。因爲每個塊組有508inode塊,51塊組前面共有51*508=25908個塊。第26275inode塊在51塊組中排在26275-25908=367的位置。查看51塊組的描述:

 

Group 51: (Blocks 1671168-1703935) [ITABLE_ZEROED]

  Checksum 0x5ffd, unused inodes 0

  Block bitmap at 1572867 (+4294868995), Inode bitmap at 1572883 (+4294869011)

  Inode table at 1574420-1574927 (+4294870548)

  34 free blocks, 1 free inodes, 541 directories

  Free blocks: 1672899, 1673339, 1673344, 1674035, 1674054, 1674062, 1674077, 16

74334, 1674353-1674354, 1674423, 1675259, 1675754-1675755, 1675763, 1675860-1675

861, 1675867, 1675979, 1676183, 1676287, 1676367, 1676507, 1676526-1676527, 1676

567, 1676711, 1676743, 1676924-1676925, 1676934, 1691649, 1691658, 1691707

  Free inodes: 422608

 

看到inode的起點位於1574420,由此,我們想要找的inode信息的塊就存在於1574787inode塊中的第二個。

可以使用blkcat查看1574787的內容,我們用vi切換到16進制模式打開如下:

 

0000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000080: 1c00 0000 4430 c1a7 c8f1 733d fc8a 6cb1  ....D0....s=..l.

0000090: 58a8 b04f 04a0 6538 0000 0000 0000 02ea  X..O..e8........

00000a0: 0706 3c00 0000 0000 2200 0000 0000 0000  ..<.....".......

00000b0: 7365 6c69 6e75 7800 0000 0000 0000 0000  selinux.........

00000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00000d0: 0000 0000 0000 0000 0000 0000 7379 7374  ............syst

00000e0: 656d 5f75 3a6f 626a 6563 745f 723a 6164  em_u:object_r:ad

00000f0: 6d69 6e5f 686f 6d65 5f74 3a73 3000 0000  min_home_t:s0...

0000100: a481 0000 c505 0000 1fd1 e750 f6b4 df50  ...........P...P

0000110: b2cd 3150 0000 0000 0000 0100 0800 0000  ..1P............

0000120: 0000 0800 0100 0000 0af3 0100 0400 0000  ................

0000130: 0000 0000 0000 0000 0100 0000 d64a 1c00  .............J..

0000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................

 

 我們知道inodesize大小爲256字節,那麼第二個inode的起始位置也就是256=0x100處。

這個時候,我們看下inode的數據結構:

 

位置

名稱

描述

0x0

__le16

i_mode

文件模式

0x2

__le16

i_uid

所有者UID.

0x4

__le32

i_size_lo

文件大小.

0x8

__le32

i_atime

讀取時間.

0xC

__le32

i_ctime

Inode修改時間

0x10

__le32

i_mtime

文件修改時間.

0x14

__le32

i_dtime

刪除時間

0x18

__le16

i_gid

GID.

0x1A

__le16

i_links_count

硬鏈接計數.

0x1C

__le32

i_blocks_lo

塊計數(512字節)

0x20

__le32

i_flags

文件標識(ext4使用extent需要標記0x80000)

...

0x28

__le32

i_block[EXT4_N_BLOCKS=15]

塊映射(ext2/3)或區段樹(ext4)

...

 

我們按照表中的結構,對照上面的塊碼:

 

偏移

大小

名稱

描述

0x0

0x81a4

i_mode

文件模式

0x2

0x0000

i_uid

所有者UID.

0x4

0x0000 05c5

i_size_lo

文件大小.

0x8

0x50e7 d11f

i_atime

讀取時間.

0xC

0x50df b4f6

i_ctime

Inode修改時間

0x10

0x5031 b2cd

i_mtime

文件修改時間.

0x14

0x0000 0000

i_dtime

刪除時間

0x18

0x0000

i_gid

GID.

0x1A

0x0001

i_links_count

硬鏈接計數.

0x1C

0x0000 0008

i_blocks_lo

塊計數(512字節)

0x20

0x0080 0000

i_flags

文件標識(ext4使用extent需要標記0x80000)

...

0x28

 ...

i_block[EXT4_N_BLOCKS=15]

塊映射(ext2/3)或區段樹(ext4)

...

 

細心的同學會發現大小的順序是倒過來的,這是因爲__lexx類型,lelittle endian小端開始的縮寫,意思就是從小到大的順序。我們看到文件的大小爲0x5c5=1477,這說明我們找的正是math.cinode

 

因爲ext4 使用區段去代替了塊映射去查找文件的內容。從40-9960個字節過去是用作塊映射的,如今用作存儲extent信息。extent結構體有12字節的大小,反應快的同學馬上會說,那麼一個inode可以存放最多5extent。然而這是不對的,因爲前12個字節(40-51)被段頭(extent header)所佔據,所以,一個inode中的區段數最多隻能是4

 

現在,我們重點開始講區段樹(extent tree)

ext4中,區段樹取代了舊式的邏輯塊映射。這是因爲在老的模式中,分配連續的1000個塊需要映射這1000個塊的地址。但使用了區段,只需要映射一個區段並把區段的長度標記爲1000ee_len=1000)。如果起用了flex_bg的功能,一個區段可以分配一個很大的文件,這降低了元數據的大小,也提高了硬盤的效率。inode必須使用區段標記0x80000開啓區段的功能。

區段的結構是樹形的。每個樹節點的起始爲:struct ext4_extent_header(這是一個結構體,我們接下來會給大家描述它的內容)。如果一個節點是樹的內部節點(即eh.eh_depth>0),那麼eh.eh_entries的指針將指向struct ext4_extent_idx;每個這些索引都指向一個塊,塊中包含更多的區段樹中的節點。如果節點是樹的葉子節點(eh.eh_depth=0),那麼eh.eh_entries的指針將指向struct ext4_extent;這些結構體中指向文件的數據塊。區段樹的根節點存在inode.i_block,也就是我們在前面討論的從40-99的那60個字節裏。

 

說了這麼多,我們還是趕緊看看extent的結構吧;

 

首先出場的是段頭(extent header)

 

偏移

大小

名稱

描述

0x0

__le16

eh_magic

幻數magic number, 0xF30A.

0x2

__le16

eh_entries

區段數.

0x4

__le16

eh_max

最大的區段數.

0x6

__le16

eh_depth

段節點在段樹中的深度。0則表示爲葉子節點,指向數據塊;否則指向其它段節點。

0x8

__le32

eh_generation

暫不討論

 

同樣的,對照我們的實際數據看看

 

偏移

大小

名稱

描述

0x0

0xf30a

eh_magic

幻數magic number, 0xF30A.

0x2

0x0001

eh_entries

區段數.

0x4

0x0004

eh_max

最大的區段數.

0x6

0x0000

eh_depth

段節點在段樹中的深度。0則表示爲葉子節點,指向數據塊;否則指向其它段節點。

0x8

0x0000 0000

eh_generation

暫不討論

 

 

接下來我們先看struct ext4_extent_idx,這個結構在前面我們有提到過,用於extent樹的內部節點。

 

偏移

大小

名稱

描述

0x0

__le32

ei_block

邏輯塊號.

0x4

__le32

ei_leaf_lo

區段樹中下一層的區段節點塊地址(低32位),可以指向葉子節點或者內部節點。

0x8

__le16

ei_leaf_hi

上一欄的高16位地址

0xA

__u16

ei_unused

未使用

 

我們接着看struct ext4_extent,葉子節點的結構體

 

偏移

大小

名稱

描述

0x0

__le32

ee_block

此區段的第一個塊號,起始塊號

0x4

__le16

ee_len

區段內包含的塊數.

0x6

__le16

ee_start_hi

此區段所指向的塊號(高16位)

0x8

__le32

ee_start_lo

此區段所指向的塊號(低32位)

 

對照我們的實際數據看看

 

偏移

大小

名稱

描述

0x0

0x0000 0000

ee_block

此區段的第一個塊號,起始塊號

0x4

0x0001

ee_len

區段內包含的塊數.

0x6

0x0000

ee_start_hi

此區段所指向的塊號(高16位)

0x8

0x001c 4ad6

ee_start_lo

此區段所指向的塊號(低32位)

 

由上表可以看到,因爲我們的文件較小,這裏作爲葉子節點直接指向了文件數據塊。數據塊號爲0x001c4ad6=1854166。我們使用命令查看塊中的內容:

[root@localhost Desktop]# blkcat /dev/mapper/VolGroup-lv_root 1854166

#include <stdlib.h>

#include <math.h>

...

 

呵呵,可以看到,這就是我們的math.c文件。

 

思考:

請讀者找一個大於4k的文件,看看能不能找到它的數據塊。

 

刪除文件

執行rm後刪除文件,數據塊並沒有被清除,inode被釋放,有下面3項會改變: 1. 文件大小被置爲0

    2. 段頭中的區段值被設爲0

    3. 區段被清空

清空了區段意味着我們會失去文件起始物理塊的地址和區段的長度。也就是說,在inode中已經不存在元數據可以幫我們恢復文件。這種行爲和ext3回收inode時清除inode中的塊指針很相似。這樣就意味着我們只能靠傳統的file-carving去恢復文件。

還記得在上一章中,我們提到過的結構體struct ext4_extent_idx。這個結構體表示在extent tree中的節點。 我們在前面的章節已經闡述過,ext4使用extent取代了傳統的block映射方式。我們的案例中只展示了只有一個extent的情況。本篇文章將介紹多個extent情況下的具體細節。

 

在本文中,我們選取了文件/var/log/messages,它是系統日誌的記錄文件,由於它的角色特殊,時間長了會造成給很多的碎片。我們還是先看看他的inode,方法和(一)中描述的一致,在此不重複了。

 

 

0000c00: 8081 0000 d036 0000 814b ee50 7f4b ee50  .....6...K.P.K.P

0000c10: 7f4b ee50 0000 0000 0000 0100 2000 0000  .K.P........ ...

0000c20: 0000 0800 0100 00000af30400 0400 0000  ................

0000c30: 0000 0000 0000 0000 0100 0000 58c2 0b00  ............X...

0000c40: 0100 0000 0100 0000 e599 1b00 0200 0000  ................

0000c50: 0100 0000 41e6 2f00 0300 0000 0100 0000  ....A./.........

0000c60: b878 1c00 275f ea72 0000 0000 0000 0000  .x..'_.r........

0000c70: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c80: 1c00 0000 c018 94d1 c018 94d1 c0e5 ea86  ................

0000c90: 9bea e850 d0a4 fcb4 0000 0000 0000 02ea  ...P............

0000ca0: 0706 4000 0000 0000 1f00 0000 0000 0000  ..@.............

0000cb0: 7365 6c69 6e75 7800 0000 0000 0000 0000  selinux.........

0000cc0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000cd0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ce0: 7379 7374 656d 5f75 3a6f 626a 6563 745f  system_u:object_

0000cf0: 723a 7661 725f 6c6f 675f 743a 7330 0000  r:var_log_t:s0..

 

 

0x0af3開始,這是extent header起始的標記,我們還是像(一)那樣,對照着表看

 

偏移

大小

名稱

描述

0x0

0xf30a

eh_magic

幻數magic number, 0xF30A.

0x2

0x0004

eh_entries

區段數.

0x4

0x0004

eh_max

最大的區段數.

0x6

0x0000

eh_depth

段節點在段數中的深度。0則表示爲葉子節點,指向數據塊;否則指向其它段節點。

0x8

0x0000

eh_generation

暫不討論

 

因爲這裏看到depth0,說明extent中指向的是數據塊。在extent header中接下來的將extent是我們把接下來的數據對應到它的表中

 

偏移

大小

名稱

描述

0x0

0x0000 0000

ee_block

此區段的第一個塊號,起始塊號

0x4

0x0001

ee_len

區段內包含的塊數.

0x6

0x0000

ee_start_hi

此區段所指向的塊號(高16位)

0x8

0x000b c258

ee_start_lo

此區段所指向的塊號(低32位)

 

接下來的12個字節

 

偏移

大小

名稱

描述

0x0

0x0000 0001

ee_block

此區段的第一個塊號,起始塊號

0x4

0x0001

ee_len

區段內包含的塊數.

0x6

0x0000

ee_start_hi

此區段所指向的塊號(高16位)

0x8

0x001b 99e5

ee_start_lo

此區段所指向的塊號(低32位)

 

再接下來的12個字節

 

偏移

大小

名稱

描述

0x0

0x0000 0002

ee_block

此區段的第一個塊號,起始塊號

0x4

0x0001

ee_len

區段內包含的塊數.

0x6

0x0000

ee_start_hi

此區段所指向的塊號(高16位)

0x8

0x00f2 e641

ee_start_lo

此區段所指向的塊號(低32位)

 

最後的12個字節 

偏移

大小

名稱

描述

0x0

0x0000 0003

ee_block

此區段的第一個塊號,起始塊號

0x4

0x0001

ee_len

區段內包含的塊數.

0x6

0x0000

ee_start_hi

此區段所指向的塊號(高16位)

0x8

0x001c 78b8

ee_start_lo

此區段所指向的塊號(低32位)

 

可以通過使用blkcat看到4個塊剛好湊成了messages文件,疑心重的同學可以把4個塊拼成一個文件,用md5sum比較一下。這裏我們並沒有想看到extent中的內部節點情況。沒關係,我們系統日誌文件時會隨着時間增長。正在筆者撰寫此文時,messages已經變大了,並且超過了16k的大小,也就是超出了4個塊。這時候我們看看messagesinode信息,方法不重複了。

 

0000c00: 8081 0000 4f51 0000 eb84 ef50 ea84 ef50  ....OQ.....P...P

0000c10: ea84 ef50 0000 0000 0000 0100 3800 0000  ...P........8...

0000c20: 0000 0800 0100 00000af3 0100 0400 0100  ................

0000c30: 0000 0000 0000 0000 7c03 1c00 0000 0b00  ........|.......

0000c40: 0100 0000 0100 0000 e599 1b00 0200 0000  ................

0000c50: 0100 0000 41e6 2f00 0300 0000 0100 0000  ....A./.........

0000c60: b878 1c00 275f ea72 0000 0000 0000 0000  .x..'_.r........

0000c70: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c80: 1c00 0000 c80e c097 c80e c097 accd 3948  ..............9H

0000c90: 9bea e850 d0a4 fcb4 0000 0000 0000 02ea  ...P............

0000ca0: 0706 4000 0000 0000 1f00 0000 0000 0000  ..@.............

0000cb0: 7365 6c69 6e75 7800 0000 0000 0000 0000  selinux.........

0000cc0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000cd0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ce0: 7379 7374 656d 5f75 3a6f 626a 6563 745f  system_u:object_

0000cf0: 723a 7661 725f 6c6f 675f 743a 7330 0000  r:var_log_t:s0..

 

 

經過一段時間的練習,同學們應該不需要對照表來識辨這些16進制碼的含義了,如果不熟練的話,可以回過頭多看幾遍。我們看到這個inode較之前有了變化。extent的區段數變成了1,區段樹的深度變成了1。區段樹深度爲1,這說明非葉子節點。

 

偏移

大小

名稱

描述

0x0

0x0000 0000

ei_block

邏輯塊號.

0x4

0x001c 037c

ei_leaf_lo

區段樹中下一層的區段節點塊地址(低32位),可以指向葉子節點或者內部節點。

0x8

0x0000

ei_leaf_hi

上一欄的高16位地址

0xA

0x000b

ei_unused

未使用

 

使用blkcat查看文件系統塊1835900的內容,

 

0000000: 0af3 0e00 5401 0000 0000 0000 0000 0000  ....T...........

0000010: 0100 0000 58c2 0b00 0100 0000 0100 0000  ....X...........

0000020: e599 1b00 0200 0000 0100 0000 41e6 2f00  ............A./.

0000030: 0300 0000 0100 0000 b878 1c00 0400 0000  .........x......

0000040: 0100 0000 2d8b 1b00 0500 0000 0100 0000  ....-...........

0000050: 9a79 1c00 0600 0000 0100 0000 0d82 1b00  .y..............

0000060: 0700 0000 0100 0000 1182 1b00 0800 0000  ................

0000070: 0100 0000 1382 1b00 0900 0000 0100 0000  ................

0000080: 1682 1b00 0a00 0000 0100 0000 1882 1b00  ................

0000090: 0b00 0000 0300 0000 034e 1c00 0e00 0000  .........N......

00000a0: 0200 0000 074e 1c00 1000 0000 0400 0000  .....N..........

00000b0: e082 0c00 0000 0000 0000 0000 0000 0000  ................

 

 

從上面的數據,我們可以看到有0x000e個區段,也就是在extent header後有14extent或者extent ixd的結構體。接着看到extent最大數爲0x0154=340,這個數字是怎麼來的呢?我們知道在一個inode裏面,這個值是4,那是因爲('extent space' - 'extent header size') / 'extent size'  (60-12)/12=4,那麼在這裏也一樣,只不過60這裏要變爲4096,因爲我們不在inode中,而是在一個塊中,即4096-12=4084,4084/12340.333,最後還剩4個字節浪費了。再接着,是樹的深度,也就是0x0000表明是葉子節點。那麼我們知道,這個文件由着14block的塊組成。有興趣的同學可以自己把文件dump出來拼一下。呵呵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章