我有一个磁盘,上面有一些Linux内核已知的文件系统。我需要获取此文件系统上当前可用的所有块的物理块号。我该怎么做?
获取可用块计数:
内核内方法:
看看文件系统实现的.statfs
超级块钩子。它们返回一个kstatfs
对象,该对象具有f_bfree
参数,即可用块的计数。你应该能够打电话给这个。
从用户空间:
df
命令是最简单的(这当然会导致内核调用statfs
- 它还能从哪里获得信息?:)
编辑:您最初的问题传达了仅获得免费块计数。
获取区块位置:
以内核的当前结构,以独立于文件系统的方式获取每个空闲块的位置,而不仅仅是总数是不可能的(并且可能会保持这种方式(。VFS 不会对文件系统如何维护其位图强加任何通用结构;位图在超级块的文件系统相关部分中进行跟踪。
因此,如果您想要一个适用于所有文件系统的解决方案,那么您就不走运了。如果您知道文件系统可能是什么,并且数量很少,则可以查看每个文件系统的用户空间fsck
代码,并添加函数以所需的格式写出位图,或者您可以修改.statfs
钩子以写出位图。
您分配一个分配所有剩余可用块的大文件的方法听起来根本不是一个好主意,尤其是在涉及期刊的情况下。它也适用于在执行此操作时写入和删除文件的活动文件系统。
这取决于文件系统 - 没有统一的接口,一些文件系统(如 JFFS(并没有真正具有自由块的概念。此外,如果挂载了文件系统,您获得的任何信息都可能立即过时。期望必须阅读文档记录不佳的文件系统内部代码。但是,您不一定必须在内核中执行此操作。例如,如果你有兴趣获得 ext[234] 可用空间位图,请查看 libext2fs 中的位图函数。一般来说,如果有一个用户空间 fsck,你可能会利用它的代码来获取你想要的信息。
无论如何,你需要这个做什么?
害怕statfs
类函数只能给我自由 fs 块的数量,而不是它们的位置。
我发现获取可用块位置的最简单方法是创建一个填充(或仅通过fallocate()
调用保留(所有可用空间的文件,使用 FIBMAP
ioctl 获取块映射并删除该文件。但由于某些原因,这样做并不完全是我想要的。
另一种方法是进入具体文件系统的较低级别,并从其驱动程序中获取可用空间位图。这对我来说是一个很好的方法,但它必须依赖于每个文件系统实现,而且它不是好:)
也许有一些我找不到的 vfs 函数,或者一些 fs ioctl 在这种情况下可以提供帮助?
无论如何,谢谢大家的回答!
你可以使用一些旧式的C,fork,然后在unix中执行一个名为"stat"的程序。您可以将该输出通过管道传输到文件,然后使用一些字符串流来解释它并查找可用块的数量。(这将涉及取总 IO 块数并减去已用 IO 块数。
我不确定是否有更简单的方法。下面是一些伪代码:
main() {
fork()
if child{
execl(stat / %B >> output.txt)
}
if parent {
wait until output.txt is populated
read in data with stringstream
calculate number of free blocks
}
}
希望有帮助。
以最佳方式从 system(( 命令捕获标准输出
系统调用可能是您正在寻找的,只需首先确保 popen 是 Linux 上的标准。我也忘了提到你应该做这样的事情:
FILE* test = popen("df","r");
因为 df 告诉您系统上可用块的数量。