I was debugging a fuse filesystem that was reporting wrong sizes for du. It turned out that it was putting st_size / st_blksize [*] into st_blocks of the stat structure. The Linux manual page for stat(2) says:

struct stat {
    off_t     st_size;    /* total size, in bytes */
    blksize_t st_blksize; /* blocksize for file system I/O */
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */

What is st_blksize for if st_blocks is in 512B blocks anyway?

[*] which looks wrong anyway, as integer division doesn't account for the fractional part…

  • 1
    By historical reason. All UNIXes use block (512 bytes) instead of kilobyte because in the past the size of disk sector was 512 bytes Commented May 26, 2019 at 15:25
  • You should put st_blocks = (st_size + 511) / 512 -- maybe needlessly obfuscating it through an obtuse macro like ROUNDING_UP_DIV_BY_SECTORS() so the 1st midwit that comes along is impressed by the professional looking code instead of start carping about magic numbers and things he doesn't understand;-)
    – user313992
    Commented May 27, 2019 at 7:43
  • 1
    @RomeoNinov In [4]: os.stat('/vmlinuz').st_blksize Out[4]: 4096 MAGIC!
    – LtWorf
    Commented Feb 22, 2021 at 8:12

1 Answer 1


st_blocks is defined as

Number of blocks allocated for this object.

The size of a block is implementation-specific. On Linux it’s always 512 bytes, for historical reasons; in particular, it used to be the typical size of a disk sector.

st_blksize is unrelated; it’s

A file system-specific preferred I/O block size for this object. In some file system types, this may vary from file to file.

It indicates the preferred size for I/O, i.e. the amount of data that should be transferred in one operation for optimal results (ignoring other layers in the I/O stack).

  • Ah, so they have a different purpose actually. That explains a lot. Thanks!
    – liori
    Commented May 27, 2019 at 8:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .