0

stat() on a file, returns several fields including st_blksize. This is documented as "the 'preferred' block size for efficient filesystem I/O". The value is not used as a unit for other stat() fields, or referred to anywhere else in the POSIX standard.

statvfs() on a file, returns several fields including f_bsize. It also returns f_frsize. f_frsize is the unit for f_blocks, f_bfree, and f_bavail. f_frsize is variously called the "fundamental file system block size", and the "fragment size".

My man pages for statvfs describe f_bsize as the block size of the filesystem. This basically tells me nothing. The introduction already told me that statvfs() returns information about the filesystem as a whole.

  1. What can f_bsize be used for? What does the filesystem block size mean, if it is not equal to the "fundamental filesystem block size"?

  2. Is f_bsize the same thing as st_blksize on Linux and BSD and/or UNIX? Let's ignore the possibility of a FUSE filesystem contrived with the sole reason of breaking this rule. And the same for NFS servers. I'm also not very concerned that f_bsize represents a filesystem-wide value, which might be overridden for specific files.

  3. Am I right to think that unlike st_blksize, POSIX does not suggest any particular meanings for f_bsize?

sourcejedi
  • 50,249
  • This field exists. It is reasonable to think that there was likely a reason it was created, and ask what that reason was. No? – sourcejedi Aug 18 '18 at 15:21
  • Apparently not. I will explicitly say that I wanted this answer as research for the answer https://unix.stackexchange.com/a/463322/29483 , which seems to have some uncontroversial usefulness. Would really appreciate any feedback how to write a better Q&A for this research! – sourcejedi Aug 18 '18 at 17:30

1 Answers1

1

FreeBSD documents the following:

f_frsize - The size in bytes of the minimum unit of allocation on this file system. (This corresponds to the f_bsize member of struct statfs.)

f_bsize - The preferred length of I/O requests for files on this file system. (Corresponds to the f_iosize member of struct statfs.)

The statvfs() and fstatvfs() functions fill the structure pointed to by buf with garbage. This garbage will occasionally bear resemblance to file system statistics, but portable applications must not depend on this.

The statvfs() and fstatvfs() functions conform to IEEE Std 1003.1-2001 (``POSIX.1''). As standardized, portable applications cannot depend on these functions returning any valid information at all. This implementation attempts to provide as much useful information as is provided by the underlying file system, subject to the limitations of the specified data types.

The stat command in GNU coreutils can also show "fundamental block size" and "block size". It documents the latter as "(for faster transfers)".

I expect these are all accurate to the original meanings. The POSIX documentation for st_blksize says "In some file system types, this may vary from file to file". This suggests one reason why POSIX avoids specifying f_bsize as having any particular meaning. (Another is the concept of block size might not make the same sense on some filesystems, e.g. UIBFS)

f_bsize could also have some use if you're familiar with the specific filesystem implementation that you're querying.

Original meaning of f_frsize as "Fragment size"

It seems the description "fragment size" should be understood as originally referring to fragments on filesystems like UFS. These are an allocation unit smaller than a "block". See What is a fragment size in an ext3 filesystem?

Based on this, it seems f_frsize will usually be smaller or equal to f_bsize.

Linux ext2/ext3/ext4 did not support fragments. Some Linux filesystems may report a smaller f_frsize. Although that was a FUSE filesystem under development, and I don't know what it was or why it wanted to use "fragments" / f_frsize.

sourcejedi
  • 50,249