XFS寻址
XFS 大部分时候都会用绝对地址,即包含AG信息和相对AG偏移量的信息,但有些时候会使用相对地址“相对AG的偏移量”
[root@ip-172-31-35-68 ~]# xfs_db -r /dev/nvme1n1
xfs_db> sb 0
xfs_db> p
magicnum = 0x58465342
blocksize = 4096
dblocks = 2621440
rblocks = 0
rextents = 0
uuid = 76cef79a-56f3-49ba-ada8-ed01d066ebe6
logstart = 2097158
rootino = 128
rbmino = 129
rsumino = 130
rextsize = 1
agblocks = 163840
agcount = 16
rbmblocks = 0
logblocks = 16384
versionnum = 0xb5b5
sectsize = 512
inodesize = 512
inopblock = 8
fname = "\000\000\000\000\000\000\000\000\000\000\000\000"
blocklog = 12
sectlog = 9
inodelog = 9
inopblog = 3
agblklog = 18
rextslog = 0
inprogress = 0
imax_pct = 25
icount = 64
ifree = 59
fdblocks = 2604952
frextents = 0
uquotino = null
gquotino = null
qflags = 0
flags = 0
shared_vn = 0
inoalignmt = 8
unit = 1
width = 1
dirblklog = 0
logsectlog = 0
logsectsize = 0
logsunit = 4096
features2 = 0x18a
bad_features2 = 0x18a
features_compat = 0
features_ro_compat = 0xd
features_incompat = 0xb
features_log_incompat = 0
crc = 0x1f3bb170 (correct)
spino_align = 4
pquotino = null
lsn = 0x100000130
meta_uuid = 00000000-0000-0000-0000-000000000000
XFS默认会支持64位地址,但是一般小于2T会折叠上32位,日志的起始为0x200006 agblklog = 18(sb_agblklog
是 XFS 文件系统的超级块 (superblock
) 中的一个字段。它表示每个分配组(AG,Allocation Group)块数的对数
因此log 的block 会在 1000000000000000000110 / 2^18=8 的1000000000000000000110%2^18=3 偏移 ,即日志在AG7 的 第三个block开始
我们算出了逻辑偏移但还是需要计算物理偏移
(AG number) * (blocks per AG) + (relative block offset)
8 * 163840 + 3
dd if=/dev/nvme1n1 bs=4096 skip=$((8*163840 + 3)) count=1 | hexdump -C
再来计算一个文件,通过文件查询BMAP来找到对应的bloc
首先查看/mnt/testxfs/hello的inode为133,内容是hello word
[root@ip-172-31-35-68 ~]# xfs_db -r /dev/nvme1n1
xfs_db> inode 133
xfs_db> bmap
data offset 0 startblock 10 (0/10) count 1 flag 0
按照前面的方法计算物理偏移
(AG number) * (blocks per AG) + (relative block offset)
0 * 163840 + 10
然后通过dd将blockdd出来查看1047040
再来个复杂点的
[root@ip-172-31-35-68 log]# ll -i secure-20240721
8524693 -rw-r--r--. 1 root root 35006 Jul 20 17:07 secure-20240721
xfs_db> inode 8524693
xfs_db> bmap
data offset 0 startblock 1072956 (1/24380) count 1 flag 0
data offset 1 startblock 1073378 (1/24802) count 1 flag 0
data offset 2 startblock 1073375 (1/24799) count 2 flag 0
data offset 4 startblock 1073420 (1/24844) count 1 flag 0
data offset 5 startblock 1073443 (1/24867) count 2 flag 0
data offset 7 startblock 1085579 (1/37003) count 1 flag 0
data offset 8 startblock 1085592 (1/37016) count 1 flag 0
#提取part
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 24380)) count=1 of=part1
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 24802)) count=1 of=part2
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 24799)) count=2 of=part3
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 24844)) count=1 of=part4
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 24867)) count=2 of=part5
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 37003)) count=1 of=part6
dd if=/dev/nvme0n1p1 bs=4096 skip=$((1*1047040 + 37016)) count=1 of=part7
#合并
cat part1 part2 part3 part4 part5 part6 part7 > complete_file
#对比只是多了合并时候的一个end of file
[root@ip-172-31-35-68 test]# diff complete_file secure-20240721
306d305
<
\ No newline at end of file