struct statvfs中的f_bsize和f_frsize分别代表什么意思?

7
statvfs 系统调用中使用的结构体 struct statvfs 中,有两个字段: f_bsize f_frsize 。它们究竟代表什么?或更具体地说,如果我需要获取文件系统的逻辑块大小,应该使用哪一个?
这很令人困惑,因为在Linux手册页中是这样说的:

unsigned long 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 基本文件系统块大小。

我已经google了一会儿,没能找到“基本文件系统块大小”的定义。有谁可以帮忙?
2个回答

7

这将取决于您的操作系统和文件系统。在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.
 */

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

if (retval == 0 && buf->f_frsize == 0)
    buf->f_frsize = buf->f_bsize;

“逻辑块大小”是指文件系统中块的字节数(与硬盘等物理块大小不同),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 标准的方法,尽管一些系统建议不要使用它。

非常感谢您的帮助。关于Linux内核实现的信息非常有用。看起来f_frsize在内核中是相当新的,而且不是很稳定?(就像在NFS中一样)无论如何,我决定在遇到一些实际问题之前都使用f_frsize。 - Yi Zhenfei

1

仅引用《Linux编程接口》第276页作为补充:

对于大多数Linux文件系统,f_bsizef_frsize的值是相同的。但是,某些文件系统支持块片段的概念,可以在不需要整个块时分配较小的存储单元到文件末尾。这可以避免浪费空间,否则将分配整个块并造成浪费。在这样的文件系统中,f_frsize块片段的大小f_bsize整个块的大小。(UNIX文件系统中的片段概念最初出现在20世纪80年代早期的4.2BSD Fast File System中,描述见[McKusick et al., 1984]。)


没有一个内置的Linux文件系统会将f_frsize设置为与f_bsize不同 - 除了FUSE,它只报告FUSE服务器说的任何内容。因此,它们唯一可能不同的方式是(1)外部Linux文件系统,(2)FUSE文件系统(我预计很少会使f_frsize!= f_bsize,但任意自定义代码可以做任何事情),(3)如果您的代码被移植到运行在其他操作系统上(也许是某些BSD?或某些商业Unix?) - Simon Kissane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接