5

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…

liori
  • 612
  • 4
  • 12
  • 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 – Romeo Ninov May 26 '19 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;-) –  May 27 '19 at 07:43
  • 1
    @RomeoNinov `In [4]: os.stat('/vmlinuz').st_blksize Out[4]: 4096` MAGIC! – LtWorf Feb 22 '21 at 08:12

1 Answers1

8

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).

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164