Linux内核之IO3:文件系统一致性

1 掉电与文件系统一致性

由上一节文件系统的布局分析可知,当操作一个文件时,比如往/a目录下添加一个b,即添加/a/b文件,需要修改inode bitmap, inode table, block bitmap, data block。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kB2quwRf-1598521452406)(media/9de754250737a87dd54e4facf2e843d1.png)]

这一系列的操作是非原子的,假如任何一个环节掉电,造成某些步骤丢失,就会造成数据的不完整,文件将无法正常访问。

2 append一个文件的全流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vIcuzOA5-1598521452411)(media/7b7a674ed9392aa6b1dbe5443b287fb9.png)]

而硬件是不可能原子执行的,因此会造成不一致性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iIUwyEVH-1598521452412)(media/4754d7468012abe61bca0a77c068de9f.png)]

3 模拟文件系统不一致性案例

(1) 做一个image,用来模拟磁盘

dd if=/dev/zero of=image bs=1024 count=4096

(2).格式化为ext4文件系统

mkfs.ext4 -b 4096 image

(3).mount到test目录,写入一个ok.txt文件

sudo mount -o loop image test/
cd test/
sudo touch ok.txt
cd ..
sudo umount test

(4).查看磁盘详细信息

(base) leon\@pc:\~/io\$ dumpe2fs image
dumpe2fs 1.42.13 (17-May-2015)
Filesystem volume name:  <none>
Last mounted on:     /home/leon/io/test
Filesystem UUID:     759835e3-9508-4c57-b511-9c4f7e13f0ad
Filesystem magic number: 0xEF53
Filesystem revision #:  1 (dynamic)

…

Inode count:       1024
Block count:       1024
Reserved block count:   51
Free blocks:       982
Free inodes:       1012
First block:       0
Block size:        4096
Fragment size:      4096
Blocks per group:     32768
Fragments per group:   32768
Inodes per group:     1024

…

First inode:       11
Inode size:        128
Default directory hash:  half_md4
Directory Hash Seed:   9cf91d57-8528-4d39-b6ba-5f8e2e86fcb7
Group 0: (Blocks 0-1023) [ITABLE_ZEROED]
Checksum 0x240a, unused inodes 1012
主 superblock at 0, Group descriptors at 1-1
Block bitmap at 2 (+2), Inode bitmap at 18 (+18)
Inode表位于 34-65 (+34)
982 free blocks, 1012 free inodes, 2 directories, 1012个未使用的inodes
可用块数: 8-17, 19-33, 67-1023
可用inode数: 13-1024

(base) leon\@pc:\~/io\$

可以看到inode bitmap在18个块。

(5).查看inodebitmap块

dd if=image bs=4096 skip=18 | hexdump -C -n 32

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qXcOQYYH-1598521452414)(media/4195b7c1505604e5a27f0a6e5341366f.png)]

由于ext4默认用掉11个inode,新创建的ok.txt文件后,inode bitmap用掉12位。

(6).现在模拟掉电,修改inode bitmap

vim -b image

:%!xxd –g 1

:%!xxd –r

找到inode bitmap块对应地址4096*18=0x12000

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YGyMX8dy-1598521452416)(media/5428556ea89c81c5d364dae6ba8da9f1.png)]

将bitmap改为ff 07

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLUdolXZ-1598521452418)(media/56474eff423c02007f80f0a26e9073f0.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ta1ujQ8K-1598521452419)(media/e8fba5cc120428216befa94650a04711.png)]

(7).重新mount访问,查看出错信息

(base) leon@pc:~/io/test$ sudo touch bad.txt

touch: 无法创建'bad.txt': 输入/输出错误

(base) leon@pc:~/io/test$ dmesg

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UcqZSbEo-1598521452420)(media/7f3eb39a439dc757adbef50fca1a8d2b.png)]

掉电导致的不一致性,会出现各种奇怪的问题,甚至都无法修复;

任何软件的手段只能保持一致性,无法保证不丢失数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pF3qd2iC-1598521452421)(media/b1ec8ef837fddb540f33200a813c1789.png)]

4 fsck

人为破坏data block,用fsck修复

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kdlNGbA9-1598521452422)(media/9df3d1b49f33a857f25dab1070be7154.png)]

修复原理,扫描bitmap和inode table的一致性。

早期Linux/Windows系统异常掉电后启动,都用fsck修复磁盘,速度很慢。

为提高速度,新系统都采用日志系统方式。

5 文件系统的日志

将要修改的行为,记录为一个日志,若操作磁盘过程掉电,开机根据日志回放,将磁盘操作全部重做一遍。磁盘操作完成,删除日志。

优点:保持文件系统的一致性,也提高速度。

EXT2/3/4都采用日志系统。

日志的几个阶段:

1.开始写日志

2.日志区写完日志,commited;

3.执行完一条日志,磁盘操作完成,checkpoint。

4.操作完成,free日志。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ML6qHlum-1598521452423)(media/236d20d6a2b789b695f85b206da94723.png)]

完整的日志方式,相当于每个数据都写了两遍,让系统变很慢,实际工程上会根据数据情况,做部分日志,即日志方式分为三种:速度递增,安全性递减

data=journal: 完整日志;

data = ordered: 只写元数据,且先写完数据块,再写元数据

data=writeback 只写元数据,循序不确定;ubuntu默认方式;

这样日志就分为5个阶段:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tGDv8idv-1598521452424)(media/451d03c9d9e5debd60d01a5d925f3dd7.png)]

6 文件系统的调试工具

创建一个文件t.txt,df –h

(base) leon@pc:~/io$ **sudo debugfs -R 'stat /home/leon/io/t.txt' /dev/sda7**

sudo: 无法解析主机:pc: 连接超时
debugfs 1.42.13 (17-May-2015)
Inode: 13896517  Type: regular  Mode: 0664  Flags: 0x80000
Generation: 507799365  Version: 0x00000000:00000001
User: 1000  Group: 1000  Size: 17
File ACL: 0  Directory ACL: 0
Links: 1  Blockcount: 8
Fragment: Address: 0  Number: 0  Size: 0
ctime: 0x5f40e439:2182bba0 -- Sat Aug 22 17:24:09 2020
atime: 0x5f40e43b:c9589800 -- Sat Aug 22 17:24:11 2020
mtime: 0x5f40e439:2182bba0 -- Sat Aug 22 17:24:09 2020
crtime: 0x5f40e439:208e98b8 -- Sat Aug 22 17:24:09 2020
Size of extra inode fields: 32
EXTENTS:
(0):55636171
(END)

得到文件的数据块55636171

查看数据块内容

sudo **blkcat** /dev/sda7 55636171

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5XUzmC9-1598521452425)(media/c2878208c3e0eb6f4c258d4a9b091a7e.png)]

sudo dd if=/dev/sda of=1 skip=$((55636171*8+824123392)) bs=512c count=1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1xrumpZd-1598521452426)(media/63e62721aaa6d203b5d69d022853a3d5.png)]

debugfs 根据块号查inode号

sudo debugfs -R 'icheck 55636171' /dev/sda7

根据inode号,查文件路径

sudo debugfs -R 'ncheck 13896517' /dev/sda7

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lXXRQU9j-1598521452427)(media/aa081fe3218a082f666675cc68e1052f.png)]

7 Copy On Write文件系统: btrfs

不用日志,实现文件系统一致性。每次写磁盘时,先将更新数据写入一个新的block,当新数据写入成功之后,再更新相关的数据结构指向新block。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nyMKsWN4-1598521452428)(media/6eea92bfeb58b60b1dd01d1374051601.png)]

COW稳健性系统的实现方式,有利于实现子卷和snapshot,类似git的思想:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NJOggN5z-1598521452430)(media/2bf03cb36536150a36e188c059a89007.png)]

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值