ext2文件系統
阿新 • • 發佈:2018-02-13
sys 數據恢復軟件 獲取 mon system v sparse acc clas con
下面這張圖是經典的ext2文件系統的結構圖。網上到處可以找到這種類似的圖片,但是我非要畫這個圖片的原因是為了澄清2個問題: 1 並不是所有的塊組都有超級塊和快組描述符。 2 塊組描述符GDT並不是只管理自己這個塊組的信息,相反,它管理的是所有的塊組的信息。 (inode表和數據塊的個數不一定相等,我這個圖畫多少有點問題) 我們知道,超級塊是很重要的,因為它告訴了linux 這個塊設備是怎樣組織的,它告訴linux我這個文件系統是什麽文件系統,每個塊的大小是多大(1024、2048 or 4096),每個塊組有多少個塊,inode占多少個字節。等等的信息。正是因為超級塊很重要,所以我們不能將這些信息只保存1份。試想一下,如果超級塊壞掉了,而我們只有一個塊組有超級塊,那麽就徹底完蛋了,後面接近500M的空間及裏面的數據我們都沒辦法獲得了。這是比較容易理解的。但是,是不是每個塊組都要有啟動塊呢。這就沒必要了,這也有點空間浪費。那到底把超級塊放到那些塊組呢?
最後總結一句,不是所有的塊組都有超級塊,超級塊只占1個block塊,沒錯,當blocksize為4K的時候,這個塊大多數空間是浪費的。不過還好,畢竟超級塊個數有限,浪費不了多少。 下面講述 塊組描述符: 組描述符一共32個字節,大多數的教材都會給我們一組誤解,就是每個塊組,都要有組描述符。事實上並不是這樣。我們知道,一個組描述符只占32字節,而大多數的教材都會告訴我們,一個塊組裏面的組描述符占k個塊,一個組描述符是用不了這麽多空間的。 真相只有一個,就是所有的組描述符以數組的形式存放在k個塊中。也就是說,某個塊組可能沒有組描述符,而有組描述符的塊組,k個block中存放了所有組塊的組描述符。下面我來證實:
Group 0: (Blocks 1-8192) 主 superblock at 1, Group descriptors at 2-3 保留的GDT塊位於 4-259 Block bitmap at 260 (+259), Inode bitmap at 261 (+260) Inode表位於 262-515 (+261) 7663 free blocks, 2021 free inodes, 2 directories 可用塊數: 530-8192 可用inode數: 12-2032
很久以來,就想寫一篇關於ext 家族文件系統的文章,源於我剛工作的時候,曾經一不小心rm -rf,誤刪除了很多文件,當時真想有個數據恢復軟件能幫我把數據回復了。當然學習數據恢復,首先要學習文件系統。最近工作原因,好長時間沒看學習Linux kernel 相關的東西,感覺面目可憎。扯遠了,開始我們的ext2 文件系統的探索之旅。
那些介紹ext2特征的套話我就不說了,任何一本靠譜的linux教程中都可以找到,我們直接單刀直入,開始探索。 首先生成一個ext2文件系統。我在我磁盤空間有限的Ubuntu中,劃出500M的空間來從頭學習ext2 文件系統。 dd命令用來創建一個文件,不多說了,通過執行這個dd命令生成了一個全零的大小為512000*1KB的文件,即500MB 的文件。 losetup是設定循環設備(loop service)的,循環設備可以將文件模擬成塊設備。然後在塊設備上建立我們的ext2文件系統,來進行我們的學習。所以下面用mke2fs命令將loop設備格式化成ext2文件系統。 Oh,yeah,我們終於有了ext2文件系統。 這裏需要強調下,我們調用了mke2fs的默認選項其中:- root@libin:~# dd if=/dev/zero of=bean bs=1K count=512000
- 記錄了512000 0 的讀入
- 記錄了512000 0 的寫出
- 524288000字節(524 MB)已復制,9.40989 秒,55.7 MB/秒
- root@libin:~# ll bean
- -rw-r--r-- 1 root root 524288000 2012-07-06 22:24 bean
- root@libin:~# ll -h bean
- -rw-r--r-- 1 root root 500M 2012-07-06 22:24 bean
- root@libin:~#
- root@libin:~#
- root@libin:~# losetup /dev/loop0 bean
- root@libin:~# cat /proc/partitions
- major minor #blocks name
- 7 0 512000 loop0
- 8 0 312571224 sda
- 8 1 49182966 sda1
- .......
- oot@libin:~# mke2fs /dev/loop0
- mke2fs 1.41.11 (14-Mar-2010)
- 文件系統標簽=
- 操作系統:Linux
- 塊大小=1024 (log=0)
- 分塊大小=1024 (log=0)
- Stride=0 blocks, Stripe width=0 blocks
- 128016 inodes, 512000 blocks
- 25600 blocks (5.00%) reserved for the super user
- 第一個數據塊=1
- Maximum filesystem blocks=67633152
- 63 block groups
- 8192 blocks per group, 8192 fragments per group
- 2032 inodes per group
- Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
- 正在寫入inode表: 完成
- Writing superblocks and filesystem accounting information: 完成
- This filesystem will be automatically checked every 24 mounts or
- 180 days, whichever comes first. Use tune2fs -c or -i to override.
- mkdir /mnt/bean
- mount -t ext2 /dev/loop0 /mnt/bean
- root@libin:/mnt/bean# mount
- .........
- /dev/loop0 on /mnt/bean type ext2 (rw)
- root@libin:/mnt/bean# ll
- 總用量 17
- drwxr-xr-x 3 root root 1024 2012-07-06 22:31 ./
- drwxr-xr-x 4 root root 4096 2012-07-06 22:32 ../
- drwx------ 2 root root 12288 2012-07-06 22:31 lost found/
經過我們的努力,我們終於創建好了我們的ext2文件系統。下面需要講講ext2文件系統的結構是什麽樣的了。
下面這張圖是經典的ext2文件系統的結構圖。網上到處可以找到這種類似的圖片,但是我非要畫這個圖片的原因是為了澄清2個問題: 1 並不是所有的塊組都有超級塊和快組描述符。 2 塊組描述符GDT並不是只管理自己這個塊組的信息,相反,它管理的是所有的塊組的信息。 (inode表和數據塊的個數不一定相等,我這個圖畫多少有點問題) 我們知道,超級塊是很重要的,因為它告訴了linux 這個塊設備是怎樣組織的,它告訴linux我這個文件系統是什麽文件系統,每個塊的大小是多大(1024、2048 or 4096),每個塊組有多少個塊,inode占多少個字節。等等的信息。正是因為超級塊很重要,所以我們不能將這些信息只保存1份。試想一下,如果超級塊壞掉了,而我們只有一個塊組有超級塊,那麽就徹底完蛋了,後面接近500M的空間及裏面的數據我們都沒辦法獲得了。這是比較容易理解的。但是,是不是每個塊組都要有啟動塊呢。這就沒必要了,這也有點空間浪費。那到底把超級塊放到那些塊組呢?
- Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
- struct ext2_super_block {
- __u32 s_inodes_count;
- __u32 s_blocks_count;
- __u32 s_r_blocks_count;
- __u32 s_free_blocks_count;
- __u32 s_free_inodes_count;
- __u32 s_first_data_block;
- __u32 s_log_block_size;
- __u32 s_dummy3[7];
- unsigned char s_magic[2];
- __u16 s_state;
- ...
- }
- root@libin:/mnt/bean# dumpe2fs /dev/loop0
- dumpe2fs 1.41.11 (14-Mar-2010)
- Filesystem volume name: <none>
- Last mounted on: <not available>
- Filesystem UUID: 3bff7535-6f39-4720-9b64-1dc8cf9fe61d
- Filesystem magic number: 0xEF53
- Filesystem revision #: 1 (dynamic)
- Filesystem features: ext_attr resize_inode dir_index filetype sparse_super
- Filesystem flags: signed_directory_hash
- Default mount options: (none)
- Filesystem state: not clean
- Errors behavior: Continue
- Filesystem OS type: Linux
- Inode count: 128016
- Block count: 512000
- Reserved block count: 25600
- Free blocks: 493526
- Free inodes: 128005
- First block: 1
- Block size: 1024
- Fragment size: 1024
- Reserved GDT blocks: 256
- Blocks per group: 8192
- Fragments per group: 8192
- Inodes per group: 2032
- Inode blocks per group: 254
- Filesystem created: Fri Jul 6 22:31:09 2012
- Last mount time: Fri Jul 6 22:33:28 2012
- Last write time: Fri Jul 6 22:33:28 2012
- Mount count: 1
- Maximum mount count: 24
- Last checked: Fri Jul 6 22:31:09 2012
- Check interval: 15552000 (6 months)
- Next check after: Wed Jan 2 22:31:09 2013
- Reserved blocks uid: 0 (user root)
- Reserved blocks gid: 0 (group root)
- First inode: 11
- Inode size: 128
- Default directory hash: half_md4
- Directory Hash Seed: 0140915d-91ae-43df-9d84-9536cedc0d2b
- Group 0: (Blocks 1-8192)
- 主 superblock at 1, Group descriptors at 2-3
- 保留的GDT塊位於 4-259
- Block bitmap at 260 ( 259), Inode bitmap at 261 ( 260)
- Inode表位於 262-515 ( 261)
- 7663 free blocks, 2021 free inodes, 2 directories
- 可用塊數: 530-8192
- 可用inode數: 12-2032
- ...
- Group 62: (Blocks 507905-511999)
- Block bitmap at 507905 (+0), Inode bitmap at 507906 (+1)
- Inode表位於 507907-508160 (+2)
- 3839 free blocks, 2032 free inodes, 0 directories
- 可用塊數: 508161-511999
- 可用inode數: 125985-128016
- root@libin:/mnt/bean# dd if=/dev/loop0 bs=1k count=261 |od -tx1 -Ax > /tmp/dump_hex
- 記錄了261 0 的讀入
- 記錄了261 0 的寫出
- 267264字節(267 kB)已復制,0.0393023 秒,6.8 MB/秒
- root@libin:/mnt/bean# vi /tmp/dump_hex
- 000400 10 f4 01 00 00 d0 07 00 00 64 00 00 d6 87 07 00
- 000410 05 f4 01 00 01 00 00 00 00 00 00 00 00 00 00 00
- 000420 00 20 00 00 00 20 00 00 f0 07 00 00 5f cb f7 4f
- 000430 5f cb f7 4f 01 00 1a 00 53 ef 00 00 01 00 00 00
- 000440 25 cb f7 4f 00 4e ed 00 00 00 00 00 01 00 00 00
- 000450 00 00 00 00 0b 00 00 00 80 00 00 00 38 00 00 00
- 000460 02 00 00 00 01 00 00 00 5a 65 4b 92 fe 63 43 eb
- 000470 b6 86 3e f3 6e 44 19 af 00 00 00 00 00 00 00 00
- 000480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- *
- 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
- 0004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 f9 6f 16 79
- 0004f0 b7 dc 4f 8a a1 a1 18 82 72 a7 d8 25 01 00 00 00
- 000500 00 00 00 00 00 00 00 00 25 cb f7 4f 00 00 00 00
- 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- *
- 000560 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- *
- 000800 04 01 00 00 05 01 00 00 06 01 00 00 ef 1d e5 07
最左邊一列是地址,16進制。000400=1K,換句話說,就是文件第1K個字節。000800 =2K,這就是我們朝思暮想的超級塊啊。我很激動,所以把整個超級塊都貼上了,幸好我不是靠字數來騙稿費的人,否則咱得被鄙視死。
- struct ext2_super_block {
- __u32 s_inodes_count;
- __u32 s_blocks_count;
- __u32 s_r_blocks_count;
- __u32 s_free_blocks_count;
- __u32 s_free_inodes_count;
- __u32 s_first_data_block;
- __u32 s_log_block_size;
- ...
- }
最後總結一句,不是所有的塊組都有超級塊,超級塊只占1個block塊,沒錯,當blocksize為4K的時候,這個塊大多數空間是浪費的。不過還好,畢竟超級塊個數有限,浪費不了多少。 下面講述 塊組描述符: 組描述符一共32個字節,大多數的教材都會給我們一組誤解,就是每個塊組,都要有組描述符。事實上並不是這樣。我們知道,一個組描述符只占32字節,而大多數的教材都會告訴我們,一個塊組裏面的組描述符占k個塊,一個組描述符是用不了這麽多空間的。 真相只有一個,就是所有的組描述符以數組的形式存放在k個塊中。也就是說,某個塊組可能沒有組描述符,而有組描述符的塊組,k個block中存放了所有組塊的組描述符。下面我來證實:
- struct ext2_group_desc
- {
- __u32 bg_block_bitmap; /* Blocks bitmap block */
- __u32 bg_inode_bitmap; /* Inodes bitmap block */
- __u32 bg_inode_table; /* Inodes table block */
- __u16 bg_free_blocks_count; /* Free blocks count */
- __u16 bg_free_inodes_count; /* Free inodes count */
- __u16 bg_used_dirs_count; /* Directories count */
- __u16 bg_flags;
- __u32 bg_exclude_bitmap_lo;/* Exclude bitmap for snapshots */
- __u16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap)LSB */
- __u16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap)LSB */
- __u16 bg_itable_unused; /* Unused inodes count */
- __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/
- };
Group 0: (Blocks 1-8192) 主 superblock at 1, Group descriptors at 2-3 保留的GDT塊位於 4-259 Block bitmap at 260 (+259), Inode bitmap at 261 (+260) Inode表位於 262-515 (+261) 7663 free blocks, 2021 free inodes, 2 directories 可用塊數: 530-8192 可用inode數: 12-2032
- Group 1: (Blocks 8193-16384)
- 備份 superblock at 8193, Group descriptors at 8194-8195
- 保留的GDT塊位於 8196-8451
- Block bitmap at 8452 (+259), Inode bitmap at 8453 (+260)
- Inode表位於 8454-8707 (+261)
- 7677 free blocks, 2032 free inodes, 0 directories
- 可用塊數: 8708-16384
- 可用inode數: 2033-4064
- Group 2: (Blocks 16385-24576)
- Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
- Inode表位於 16387-16640 (+2)
- 7936 free blocks, 2032 free inodes, 0 directories
- 可用塊數: 16641-24576
- 可用inode數: 4065-6096
- 000800 04 01 00 00 05 01 00 00 06 01 00 00 ef 1d e5 07
- 000810 02 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 塊組0的組描述符
- -----------------------------------------------------------------------
- 000820 04 21 00 00 05 21 00 00 06 21 00 00 fd 1d f0 07
- 000830 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 塊組1的組描述符
- -----------------------------------------------------------------------
- 000840 01 40 00 00 02 40 00 00 03 40 00 00 00 1f f0 07
- 000850 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 塊組2的組描述符
- ------------------------------------------------------------------------
- 000860 04 61 00 00 05 61 00 00 06 61 00 00 fd 1d f0 07
- 000870 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000880 01 80 00 00 02 80 00 00 03 80 00 00 00 1f f0 07
- 000890 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0008a0 04 a1 00 00 05 a1 00 00 06 a1 00 00 fd 1d f0 07
- 0008b0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0008c0 01 c0 00 00 02 c0 00 00 03 c0 00 00 00 1f f0 07
- 0008d0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0008e0 04 e1 00 00 05 e1 00 00 06 e1 00 00 fd 1d f0 07
- 0008f0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000900 01 00 01 00 02 00 01 00 03 00 01 00 00 1f f0 07
- 000910 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000fb0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000fc0 01 c0 07 00 02 c0 07 00 03 c0 07 00 ff 0e f0 07
- 000fd0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 塊組62的組描述符
- -----------------------------------------------------------------------
- 000fe0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- * 沒有塊組63
- ----------------------------------------------------------------------
- 001000 04 20 00 00 04 60 00 00 04 a0 00 00 04 e0 00 00
- Group 25: (Blocks 204801-212992)
- 備份 superblock at 204801, Group descriptors at 204802-204803
- 保留的GDT塊位於 204804-205059
- Block bitmap at 205060 (+259), Inode bitmap at 205061 (+260)
- Inode表位於 205062-205315 (+261)
- 7677 free blocks, 2032 free inodes, 0 directories
- 可用塊數: 205316-212992
- 可用inode數: 50801-52832
點擊(此處)折疊或打開
- root@libin:/mnt/bean# dd if=/dev/loop0 bs=1k skip=204802 count=2|od -tx1 -Ax > /tmp/dump_hex_
- 記錄了2+0 的讀入
- 記錄了2+0 的寫出
- 2048字節(2.0 kB)已復制,0.000160205 秒,12.8 MB/秒
- root@libin:/mnt/bean# vi /tmp/dump_hex_
- 000000 04 01 00 00 05 01 00 00 06 01 00 00 ef 1d e5 07
- 000010 02 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000020 04 21 00 00 05 21 00 00 06 21 00 00 fd 1d f0 07
- 000030 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000040 01 40 00 00 02 40 00 00 03 40 00 00 00 1f f0 07
- 000050 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000060 04 61 00 00 05 61 00 00 06 61 00 00 fd 1d f0 07
- 000070 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 000080 01 80 00 00 02 80 00 00 03 80 00 00 00 1f f0 07
- 000090 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0000a0 04 a1 00 00 05 a1 00 00 06 a1 00 00 fd 1d f0 07
- 0000b0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- ....
- 0007c0 01 c0 07 00 02 c0 07 00 03 c0 07 00 ff 0e f0 07
- 0007d0 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0007e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- *
- 000800
- root@libin:/mnt/bean# cd /home
- root@libin:/home# umount /dev/loop0
- root@libin:/home# cd /mnt/bean
- root@libin:/mnt/bean# ll
- 總用量 8
- drwxr-xr-x 2 root root 4096 2012-07-06 22:32 ./
- drwxr-xr-x 4 root root 4096 2012-07-06 22:32 ../
- root@libin:/mnt/bean# mke2fs -b 4096 /dev/loop0
- mke2fs 1.41.11 (14-Mar-2010)
- 文件系統標簽=
- 操作系統:Linux
- 塊大小=4096 (log=2)
- 分塊大小=4096 (log=2)
- Stride=0 blocks, Stripe width=0 blocks
- 128000 inodes, 128000 blocks
- 6400 blocks (5.00%) reserved for the super user
- 第一個數據塊=0
- Maximum filesystem blocks=134217728
- 4 block groups
- 32768 blocks per group, 32768 fragments per group
- 32000 inodes per group
- Superblock backups stored on blocks:
- 32768, 98304
- 正在寫入inode表: 完成
- Writing superblocks and filesystem accounting information: 完成
- This filesystem will be automatically checked every 39 mounts or
- 180 days, whichever comes first. Use tune2fs -c or -i to override
ext2文件系統