1.通过dd命令创建一个文件,块大小为4096字节,个数为1024
dd if=/dev/zero of=image bs=4096 count=1024
2.格式化为ext4,块大小为4096
mkfs.ext4 -b 4096 image
3.打印当前块设备的信息
root@Jon:/home/jon/test# dumpe2fs image
dumpe2fs 1.42.13 (17-May-2015)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 80ac4dfd-dfab-4063-8248-49362781d881
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 1024
Block count: 1024
Reserved block count: 51
Free blocks: 982
Free inodes: 1013
First block: 0
Block size: 4096
Fragment size: 4096
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 1024
Inode blocks per group: 32
Flex block group size: 16
Filesystem created: Mon Dec 10 15:24:35 2018
Last mount time: n/a
Last write time: Mon Dec 10 15:24:35 2018
Mount count: 0
Maximum mount count: -1
Last checked: Mon Dec 10 15:24:35 2018
Check interval: 0 (<none>)
Lifetime writes: 73 kB
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: 10d0f008-5351-44cb-875f-8ea8671eb1a0
Group 0: (Blocks 0-1023) [ITABLE_ZEROED]
Checksum 0xc5d2, unused inodes 1013
Primary superblock at 0, Group descriptors at 1-1
Block bitmap at 2 (+2), Inode bitmap at 18 (+18)
Inode table at 34-65 (+34)
982 free blocks, 1013 free inodes, 2 directories, 1013 unused inodes
Free blocks: 8-17, 19-33, 67-1023
Free inodes: 12-1024
4.获取磁盘中某一个DataBlock中的信息
我们得出Inode的Bitmap位于第18块,因此我们skip掉前面的data block,看看Inode的元数据区信息(总共打印出32个字节)
root@Jon:/home/jon/test# dd if=image bs=4096 skip=18 | hexdump -C -n
32
00000000 ff 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
其中ff 07,意味着bit0-bit10这11个bit被占用了,因此下一个文件的inode肯定是从bit11开始的了
继续:我们新建一个文件,其inode号从12开始
root@Jon:/home/jon/test# mkdir aaa
root@Jon:/home/jon/test# mount -o loop image aaa
root@Jon:/home/jon/test# cd aaa
root@Jon:/home/jon/test/aaa# ls
lost+found
root@Jon:/home/jon/test/aaa# echo hello world > nihao
root@Jon:/home/jon/test/aaa# ls -i nihao
12 nihao
root@Jon:/home/jon/test/aaa#
然后再umount掉
root@Jon:/home/jon/test/aaa# cd ..
root@Jon:/home/jon/test# umount aaa/
root@Jon:/home/jon/test# dd if=image bs=4096 skip=18 | hexdump -C -n 32
00000000 ff 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
OK,很明显Inode的bitmap从ff 07变更为了ff 0f。说明第12个inode被占用了
我们再手动将Inode bitmap改回去看看,使用UE打开image文件,定位到4096*18的位置如下:
改为如下:
再次用dd命令查看
root@Jon:/home/jon/test# dd if=image bs=4096 skip=18 | hexdump -C -n
32
00000000 ff 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
确认inode的bitmap已经改回来了,之后再调用fsck看能否修复磁盘
root@Jon:/home/jon/test# fsck.ext4 image
e2fsck 1.42.13 (17-May-2015)
image: clean, 12/1024 files, 43/1024 blocks
很遗憾,修复失败
root@Jon:/home/jon/test# dd if=image bs=4096 skip=18 | hexdump -C -n 32
00000000 ff 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
我们再mount这个文件
root@Jon:/home/jon/test# mount -o loop image aaa/
root@Jon:/home/jon/test# cd aaa/
root@Jon:/home/jon/test/aaa# ls
lost+found nihao
root@Jon:/home/jon/test/aaa# ls -i nihao
12 nihao
我们现在干点坏事
root@Jon:/home/jon/test/aaa# echo hello > buhao
bash: buhao: Input/output error
错误原因很明显,因为inode 12在Bitmap中已经拿掉了,但是文件系统却没有更新,导致第二个文件在创建的时候出现冲突
[1487589.384725] EXT4-fs error (device loop3): __ext4_new_inode:1115: comm bash: failed to insert inode 12: doubly allocated?
5.文件系统的一致性问题
如上面流程,Inode 12被从Bitmap中拿掉后,但是datablock,以及目录信息等都没有更新的情况下,再去新建文件出错,这样导致的文件系统不一致,可以通过fsck工具修复
root@Jon:/home/jon/test# fsck.ext4 image
e2fsck 1.42.13 (17-May-2015)
Group descriptor 0 has invalid unused inodes count 1012. Fix<y>? yes
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free inodes count wrong for group #0 (1011, counted=1012).
Fix<y>? yes
Free inodes count wrong (1011, counted=1012).
Fix<y>? yes
image: ***** FILE SYSTEM WAS MODIFIED *****
image: 12/1024 files (0.0% non-contiguous), 43/1024 blocks
如果我们只是修改datablock的bitmap信息,fsck很可能无法为我们检测出异常,那么我们也可以通过fsck.ext4 -f来强制修复
root@Jon:/home/jon/test# fsck.ext4 -f image
e2fsck 1.42.13 (17-May-2015)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
image: 13/1024 files (0.0% non-contiguous), 44/1024 blocks