Subject: bug#10561: stat unclear about size on disk and type of blocks discussed

From: Pádraig Brady <[email-masked]>
Date: Fri, 20 Jan 2012 12:27:34 +0000

On 01/20/2012 07:16 AM, Filipus Klutiero wrote:
> Today I tried figuring out how much disk space a small file took. I used stat, but that turned out surprisingly difficult:

First of all, `du` is probably a better tool to this use case. Anyway...

>> # LANG=C stat htpasswd.setup
>>   File: `htpasswd.setup'
>>   Size: 54              Blocks: 8          IO Block: 4096   regular file
>> Device: 805h/2053d      Inode: 5268976     Links: 1
>> Access: (0640/-rw-r-----)  Uid: (    0/    root)   Gid: (   33/www-data)
>> Access: 2012-01-19 15:00:58.000000000 -0500
>> Modify: 2012-01-19 15:00:54.000000000 -0500
>> Change: 2012-01-19 15:00:54.000000000 -0500
>>  Birth: -
>> root@vinci:/etc/phpmyadmin#
> 
> The "real" size is clear, but at first I thought that didn't say the size on disk.
> 
> There are 3 interesting format sequences:
> 
>> %b
>>  Number of blocks allocated (see %B)
>> %B
>>  The size in bytes of each block reported by %b
> 
>> %o
>>  I/O block size
> 
> In the default format, %b is shown as "Blocks" and %o is shown as "IO Block".
> On my system, there are 2 kinds of blocks, those on the HDD, 512 bytes each, and those of the filesystem, 4096 each. The manual's descriptions do not make it clear which kind of block is referred to. After verification, %b refers to HDD blocks.

Well %B may not always refer to "HDD blocks".
Just interpret it as described.
I.E. an abstract multiplier for %b.

To be concrete about block sizes, there are generally 3 to consider:

1. physical     defined by the hardware device
2. logical      the smallest addressable unit used for the device
3. file system  ditto for the file system

Traditionally one had a physical block size of 512,
but a larger logical size of say 4096, with the size
determining the usual I/O ops vs fragmentation trade-off.

One can query 1. and 2. like:

# strace -e ioctl blockdev --getpbsz /dev/sda
ioctl(3, BLKPBSZGET, 512)               = 0
512
# strace -e ioctl blockdev --getbsz /dev/sda
ioctl(3, BLKBSZGET, 4096)               = 0
4096

`stat` works at the file and file system level,
so 3. can be queried like:

$ stat -f -c "%S" .
4096

> As for %o, if you'd ask me what "I/O block size" means without any context, I'm far from being sure I would answer it means size on disk. I suggest to call this Size on disk, or Size used on the filesystem.

I/O implies transfer.
So it corresponds to an "optimal transfer size hint"
This value can be different at each layer, for example:

$ stat -c "%o" .                # file level
$ stat -f -c "%s" .             # file system level
# blockdev --getioopt /dev/sda  # device level

> I'm not sure what language should be used instead. Perhaps instead of blocks the manual should talk about "data storage device blocks".

I suppose we could clarify "I/O block size" a bit.
How about s|I/O block size|optimal I/O block transfer size|

cheers,
Padraig.