Reputation: 166
In struct statvfs
(which is used by the statvfs
syscall), there are two fields: f_bsize
and f_frsize
. What exactly do they stand for? Or to be more specific, if I need to get the logical block size of the filesystem, which one should I use?
It is very confusing, because in the Linux man page, it is said:
unsigned long f_bsize; /* file system block size */
unsigned long f_frsize; /* fragment size */
It seems like f_bsize is the logical block size which I need, while in the man page of macOS, it is said:
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.)
It seems like f_frsize is the logical block size, finally I checked the POSIX standards, and here is the specification:
unsigned long f_bsize File system block size.
unsigned long f_frsize Fundamental file system block size.
I have googled for a while and failed to find the definition of the "Fundamental file system block size. Is there anybody who can help?
Upvotes: 9
Views: 5790
Reputation: 1033
Just cite the The Linux Programming Interface (Page 276) as a supplement:
For most Linux file systems, the values of
f_bsize
andf_frsize
are the same. However, some file systems support the notion of block fragments, which can be used to allocate a smaller unit of storage at the end of the file if a full block is not required. This avoids the waste of space that would otherwise occur if a full block was allocated. On such file systems,f_frsize
is the size of a fragment, andf_bsize
is the size of a whole block. (The notion of fragments in UNIX file systems first appeared in the early 1980s with the 4.2BSD Fast File System, described in [McKusick et al., 1984].)
Upvotes: 4
Reputation: 731
It will depend on your operating system and file system. On linux, f_frsize is rarely (if ever) going to be different than f_bsize - quickly searching the kernel source finds only one real use case (in the nfs server code) where f_frsize is set, and it comes with the following notes:
/*
* 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.
*/
And in fs/statfs.c, frsize will be set to bsize if a given file system driver does not set it:
if (retval == 0 && buf->f_frsize == 0)
buf->f_frsize = buf->f_bsize;
'logical' block size is the size in bytes of the blocks on the file system (vs physical block size on a hard drive for instance), and this is what is indicated by f_bsize.
It seems to me that the POSIX specification is intentionally vague, and it's up to each file system to determine/document the exact meaning of the two fields. I would personally take 'fundamental file system block size' to mean the size of the smallest amount of data that a single file can allocate, a kind of base unit of the file system.
Maybe I've gone on a bit of a tangent though -
Perhaps there is some confusion due to statvfs vs statfs, which are different functions/structures, both of which have members with names f_frsize and f_bsize, which don't have the same meaning across both structures.
What the MacOS documentation is saying is that the statvfs.f_frsize has the same meaning as statfs.f_bsize, and statvfs.f_bsize is likewise equivalent to statfs.iosize.
So you can use statfs.f_bsize or statvfs.f_frsize to determine the logical block size of a file system. statvfs is the newer and POSIX standard way, though some systems recommend against its usage.
Upvotes: 9