struct statvfs 中的 f_bsize 和 f_frsize 代表什么?

Yi *_*fei 6 c linux filesystems macos

struct statvfs(由statvfs系统调用使用)中,有两个字段:f_bsizef_frsize。它们究竟代表什么?或者更具体地说,如果我需要获取文件系统的逻辑块大小,我应该使用哪一个?

这很令人困惑,因为在 Linux 手册页中,是这样说的:

无符号长 f_bsize; /* 文件系统块大小 */
unsigned long f_frsize; /* 片段大小 */

似乎 f_bsize 是我需要的逻辑块大小,而在 macOS 的手册页中,它说:

f_frsize 此文件系统上最小分配单元的大小(以字节为单位)。(这对应于 struct statfs 的 f_bsize 成员。)
f_bsize 此文件系统上文件的 I/O 请求的首选长度。(对应于 struct statfs 的 f_iosize 成员。)

好像 f_frsize 是逻辑块大小,最后我查了 POSIX 标准,这里是规范:

unsigned long f_bsize 文件系统块大小。
unsigned long f_frsize 基本文件系统块大小。

我已经用谷歌搜索了一段时间,但没有找到“基本文件系统块大小”的定义。有人可以帮忙吗?

Sha*_*awn 5

这将取决于您的操作系统和文件系统。在 linux 上,f_frsize 很少(如果有的话)与 f_bsize 不同——快速搜索内核源代码只会找到一个真实的用例(在 nfs 服务器代码中),其中设置了 f_frsize,它带有以下注释:

/*
 * Current versions of glibc do not correctly handle the
 * case where f_frsize != f_bsize.  Eventually we want to
 * report the value of wtmult in this field. 
 * (wtmult is presumed to be the nfs server's disk block size)
 */
buf->f_frsize = dentry->d_sb->s_blocksize;

/*
 * On most *nix systems, f_blocks, f_bfree, and f_bavail
 * are reported in units of f_frsize.  Linux hasn't had
 * an f_frsize field in its statfs struct until recently,
 * thus historically Linux's sys_statfs reports these
 * fields in units of f_bsize.
 */
Run Code Online (Sandbox Code Playgroud)

在 fs/statfs.c 中,如果给定的文件系统驱动程序没有设置,frsize 将设置为 bsize:

if (retval == 0 && buf->f_frsize == 0)
    buf->f_frsize = buf->f_bsize;
Run Code Online (Sandbox Code Playgroud)

“逻辑”块大小是文件系统上块的字节大小(例如与硬盘驱动器上的物理块大小),这就是 f_bsize 所指示的。

在我看来,POSIX 规范是故意含糊的,由每个文件系统来确定/记录这两个字段的确切含义。我个人认为“基本文件系统块大小”是指单个文件可以分配的最小数据量的大小,是文件系统的一种基本单位。

也许我已经有点切线了——

由于 statvfs 与 statfs 是不同的函数/结构,两者都有名称 f_frsize 和 f_bsize 的成员,这两个结构的含义不同,因此可能存在一些混淆。

MacOS 文档说的是 statvfs.f_frsize 与 statfs.f_bsize 具有相同的含义,并且 statvfs.f_bsize 同样等效于 statfs.iosize。

因此,您可以使用 statfs.f_bsize 或 statvfs.f_frsize 来确定文件系统的逻辑块大小。statvfs 是较新的 POSIX 标准方式,尽管有些系统不推荐使用它。