What, exactly, are stat.st_blocks, statfs.f_bsize?

Jonathan I. Kamens jik at athena.mit.edu
Tue Feb 26 07:59:32 AEST 1991


  My "delete" application wants to be able to tell exactly how much space on a
disk is actually occupied by a file.  This involves two things:

1. Finding out how many disk blocks the file occupies.
2. Finding out the size of each block.

Now, on a 4.3BSD system, the stat structure contains the st_blocks field,
which tells the "actual number of blocks allocated."  Given that
description, the question becomes, what exactly is a "block?"  There are two
possible answers:

1. The size specified by DEV_BSIZE.
2. The size in the f_bsize field of the statfs structure of the filesystem on
   which the file resides.

Now, it seemed to me that f_bsize would be the logical choice, since different
filesystems can have different minimum block sizes, but some experimentation
indicates that actually, DEV_BSIZE is what's being used.  The 4.3reno stat(2)
man page goes even further; it describes st_blocks as "The actual number of
blocks allocated for the file in 512-byte units."  But that leaves me with
another question -- is it DEV_BSIZE, or 512 bytes?

  Besides all of these problems, we have the problem that some Unix
implementations (POSIX systems, in particular) don't even have an st_blocks
structure, so all I've got to work with is st_size.

  So, I would like to ask if the following outlined method of determining the
actual space usage of a file on many different flavors of Unix is reliable:

#include <sys/param.h> /* for DEV_BSIZE */

int actual_bytes;
struct stat statbuf;

... assume statbuf is initialized ...

#ifdef ST_BLOCKS_EXISTS /* I'll define this myself, as necessary */
#ifdef DEV_BSIZE
actual_bytes = statbuf.st_blocks * DEV_BSIZE;
#else
actual_bytes = statbuf.st_blocks * 512;
#endif /* DEV_BSIZE */
#else /* ! ST_BLOCKS_EXISTS */
#ifdef DEV_BSIZE
actual_bytes = DEV_BSIZE * (statbuf.st_size / DEV_BSIZE + 
                            ((statbuf.st_size % DEV_BSIZE) ? 1 : 0));
#else
actual_bytes = statbuf.st_size;
#endif /* DEV_BSIZE */
#endif /* ST_BLOCKS_EXISTS */

  One final question: I thought that f_bsize was the minimum block size for a
filesystem, but when statfs()ing certain filesystems, I find it possible to
create a file that takes up much less space than what f_bsize says.  So, what
is f_bsize supposed to represent?

  Thanks for any help you can provide!
-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik at Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710



More information about the Comp.unix.wizards mailing list