Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do f_bsize and f_frsize in struct statvfs stand for?

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?

like image 528
Yi Zhenfei Avatar asked Feb 22 '19 09:02

Yi Zhenfei


People also ask

What does the function statvfs () return about a mounted filesystem?

The function statvfs () returns information about a mounted filesystem. path is the pathname of any file within the mounted filesystem. buf is a pointer to a statvfs structure defined approximately as follows: struct statvfs { unsigned long f_bsize; /* Filesystem block size */ unsigned long f_frsize; /* Fragment size */ fsblkcnt_t ...

What is fstatfs () in Linux?

Some values were too large to be represented in the returned struct. The Linux kernel has system calls statfs () and fstatfs () to support this library call. uses the f_frsize, f_frsize, and f_bsize fields of the return value of statvfs (path,buf).

What does (statvfs () ) mean?

( statvfs ()) Search permission is denied for a component of the path prefix of path. (See also path_resolution (2).) ( fstatvfs ()) fd is not a valid open file descriptor. Buf or path points to an invalid address. This call was interrupted by a signal. An I/O error occurred while reading from the file system.

What is the difference between EXEC (2) and fstatvfs ()?

Bits defined by POSIX are Read-only file system. Set-user-ID/set-group-ID bits are ignored by exec (2). It is unspecified whether all members of the returned struct have meaningful values on all filesystems. fstatvfs () returns the same information about an open file referenced by descriptor fd. On success, zero is returned.


1 Answers

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.

like image 96
Shawn Avatar answered Nov 04 '22 03:11

Shawn