What the “Blocks” value (the
st_blocks field of a
struct stat) measures exactly is not standardized.
Traditionally, it counts the number of blocks that are used for filesystem content; this value multiplied by the block size is equal to the file size, rounded up to the nearest multiple of the block size. There's an exception: if the file is a sparse file, then it uses fewer blocks. This leaves several things unaccounted:
- Space consumed by the file's metadata: timestamps, permissions, etc. In the traditional Unix layout, this is stored in an inode, but modern filesystems can have large metadata (for access control lists, extended security attributes, etc.) which doesn't always fit in a fixed-size inode.
- Space consumed by indirect blocks: for large files, the list of blocks that contain file contents can itself use up many blocks.
- Space consumed by the directory entry (or entries, if the file has multiple hard links). This space is accounted for in the size of the directory itself.
I don't know of a filesystem that reports the inode size as part of the
st_blocks value. Most Unix filesystems have a layout that separates inodes from the rest of the content, and track inode usage and block usage separately. Some filesystems include indirect blocks in
st_blocks, others don't.
There are other things that can cause differences between the block size and the content size. For example, on a compressed filesystem, the relationship depends on how much the file can be compressed. Some filesystems can share a block between several small files or tails of larger files, e.g. a 1024-byte block could contain both a 200-byte file and the last 100 bytes of a 1124-byte file, and that block would be counted in the
st_blocks value for both files.
The “IO Block” value (
st_blksize field of
struct stat) is not related to the “Blocks” value in any way. The
st_blksize value is a hint to applications that they'll get better performance if they use a buffer of this size when reading or writing to the file. On a modern system with complex performance characteristics, it may or may not have any relevance.
On many systems, the unit for the
st_blocks value is the
f_bsize value from
struct statvfs. This unit can vary between filesystems (even filesystems of the same type, e.g. ext4 can use 1024, 2048 or 4096). I think that's always the case on Linux, but it isn't guaranteed by POSIX. On Linux, you can display the
f_bsize value with
du utility will make the correct calculation when it calculates the disk usage for a file: what
du does is to multiply the
st_blocks value by the appropriate block size (so it won't include the inode on most systems).
There's no generic way to find the size of an inode. Some filesystem types use fixed-sized inodes, which you can look up in the definition of the filesystem. Some filesystem types use a fixed size for a given filesystem, which you can query with a utility (e.g.
tune2fs for ext).