What, exactly, are stat.st_blocks, statfs.f_b

Guy Harris guy at auspex.auspex.com
Tue Mar 5 19:10:35 AEST 1991


>Yep.  The fact that there is no way in SunOS (prior to 4.0 or 4.1, since
>those are supposed to be SysVr4 compatible,

Umm, no, they're not.  Some Sun Marketoons may have claimed, without
proper qualification, that they're completely compatible; they're pretty
close, but they're *not* completely compatible.  SunOS 4.x has the same
"statfs()" call that SunOS releases prior to 4.x did.

>which is SysVr3.2 compatible, meaning it should have the statfs() call)

S5R4 does, I presume, have the same "statfs()" call as S5R3; however the
call you're *supposed* to use in S5R4 is "statvfs()", which is a new
call in S5R4, atoning for S5R3's error in having a "statfs()" call with
the same name as SunOS's but incompatible semantics.

You don't need to use that call to find out the units of "st_blocks",
though; the S5R4 manual states that "st_blocks" is "the total number of
physical blocks of size 512 bytes actually allocated on disk."

Presumably, if the allocation granularity of the disk, or of the file
system, is in blocks that are some multiple of 512 bytes in size, the
number-of-blocks will be multiplied by that multiple to get the number
of 512-byte chunks.  If it's the units are less than 512 bytes, the
system'd have to *divide* by the ratio of sizes, and if the ratio of
sizes isn't integral, you'd have a problem; fortunately, I suspect most
UNIX systems have disks whose sector size is some multiple of 512 bytes
(the only exceptions may be assorted mainframes, such as IBM mainframes,
although the UNIXes on those systems may, when not working on
fixed-block-size disks, use some standard block size - I don't think
anybody's ported UNIX to the IBM 1130, so that doesn't count... :-)).

The SunOS documentation doesn't say what the units are, but "st_blocks"
is in units of 512 bytes on UFS and on NFS to most if not all UNIX
servers, and should be in units of 512 bytes on any other file systems
plugged into your system.

The NFS protocol spec does not, alas, do a very good job of explaining
the fields of the "fattr" structure, so it's conceivable that a server
writer may not return a file size in 512-byte units in the "blocks"
field.

It *should* have indicated that the "blocksize" field is the block size
*recommended for I/O*, rather than the block size used as units for the
"blocks" field, as the "blocksize" field is what gets turned into the
"st_blksize" field, and that field - in BSD, in SunOS, and in S5R4 - is
the recommended block size for I/O operations.  It should also have
indicated that the "blocks" field should be in units of 512 bytes.

As for "statfs()" a la SunOS, "statfs()" a la S5R3, and "statvfs()" a la
S5R4 (including, I assume, Sun's current "developer's release" of S5R4,
and any future Sun releases of S5R4):

	SunOS "struct statfs" includes:

                 long    f_bsize;    /* fundamental file system block size */
                 long    f_blocks;   /* total blocks in file system */
                 long    f_bfree;    /* free blocks */
                 long    f_bavail;   /* free blocks available to non-super-user */

	where "f_bsize" is the unit of allocation of the particular file
	system - i.e., on a BSD/UFS file system, the "fragment size",
	which may be bigger than the sector size; it's typically 1K on
	Sun systems, even though the sector size is 512 bytes.

	"st_bfree" and "st_bavail" are in units of "f_bsize", not units
	of 512 bytes.

	(Determined by checking the code; it's not well-documented.)

	S5R3's "struct statfs" includes:

		long	f_bsize;	/* Block size */
		long	f_frsize;	/* Fragment size (if supported) */
		long	f_blocks;	/* Total number of blocks on file system */
		long	f_bfree;	/* Total number of free blocks */

	where "f_bsize" is, on S5 file systems, the unit of allocation
	of the particular file system - i.e., on a 1K file system, it's
	1K, and on a 512-byte file system, it's 512 bytes.  "f_frsize"
	is 0.  (All as of S5R3.1, from checking the code.)

	Dunno what's done on S5 systems that support a BSD file system;
	one presumes the idea is that "fs_bsize" is the "block size",
	and "fs_fsize" is the "fragment size", the *latter* being the
	true unit of allocation, and the former being more the suggested
	unit of I/O.

	"f_blocks" and "f_bfree" are in units of 512-byte chunks.

	S5R4's "struct statvfs" includes:

		ulong	f_bsize;	/* preferred file system block size */
		ulong	f_frsize;	/* fundamental filesystem block size
					(if supported) */
		ulong	f_blocks;	/* total # of blocks on file system
					in units of f_frsize */
		ulong	f_bfree;	/* total # of free blocks */
		ulong	f_bavail;	/* # of free blocks avail to
					     non-superuser */

	I'm not sure what this "(if supported)" nonsense is for
	"f_frsize"; if it's not "supported", the "f_blocks" and,
	presumably, "f_bfree" and "f_bavail" fields are meaningless, as
	the former is documented as being in units of "f_frsize" and the
	other two are, I assume, also in those units.

	I suspect that, for an S5 file system, both "f_bsize" and
	"f_frsize" are supported; dunno whether the latter is 512 or the
	block size of the file system.  Dunno whether "f_bsize"
	is the block size of the file system, or 512, or 1024, or what.

	For a BSD/UFS file system, "f_bsize" is probably the block
	size (recommended I/O size) and "f_frsize" is probably the
	fragment size (unit of allocation).

	(Determined from reading the documentation.)



More information about the Comp.unix.internals mailing list