我试图了解如何从 ext4 文件系统中的 inode 计算扇区号。因此,我正在阅读ext4_mpage_readpages功能。
功能简介:在读请求期间,如果在页缓存中没有找到该页,则分配一个新页并将其添加到页缓存中。之后调用上面的函数从磁盘获取数据并填充到页面中。
我知道一个页面的大小是4096字节,而块是512字节(因此,一个页面由8个块组成)。据我了解,上述函数将块号映射到中的页面块[页块]在这些地方:这里和这里。映射块后,该函数分配一个bio,分配扇区读取,并调用 generic_make_request() 从磁盘读取数据。
我对理解上述函数如何计算给定地址空间映射的扇区感到困惑。有没有其他方法可以从 ext4 文件系统中的 inode 获取扇区号?
答案1
filefrag -v /path/to/file
最简单的方法是运行可以作为普通用户运行的命令(与debugfs
需要对块设备的读取访问权限不同,通常仅针对 root 用户)。这将为您提供 ext4 物理块号(通常为 4096 字节)相对于文件内相应逻辑偏移量的分区开头。您还可以使用filefrag -v -k
KiB 为单位或filefrag -v -b1
1 字节“块”。
$ filefrag -vb1 google-chrome-stable_current_x86_64.rpm
Filesystem type is: ef53
File size of google-chrome-stable_current_x86_64.rpm is 57333190
(57335808 blocks of 1 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 8388607: 5872025600..5880414207: 8388608:
1: 8388608..16777215: 5897191424..5905580031: 8388608: 5880414208:
2: 16777216..25165823: 6241124352..6249512959: 8388608: 5905580032:
3: 25165824..33554431: 8019509248..8027897855: 8388608: 6249512960:
4: 33554432..41943039: 8128561152..8136949759: 8388608: 8027897856:
5: 41943040..50331647: 8220835840..8229224447: 8388608: 8136949760:
6: 50331648..57335807: 28538081280..28545085439: 7004160: 8229224448: last,eof
这是用来ioctl(fd, FS_IOC_FIEMAP, ...)
请求文件描述符的范围映射,而文件描述符又使用->fiemap()
最常见的文件系统的方法。使用了很多旧的内核ioctl(fd, FS_IOC_FIBMAP, ...)
,但它一次只能映射一个块,并且今天可能需要对大文件进行数百万次调用。