File block size – difference between stat and ls

filesystemslsstatUtilities

I've noticed that when I do a:

ls -ls file

It provides block count, say 8 blocks.

When I do:

stat file

I notice that the block count is 16, twice the number given by ls.

The block size on my file system is 4096. I learned that the arbitrary unit for blocks used by ls is 1024. Is it correct to say that stat uses an arbitrary unit of 512 bytes when reporting blocks?

If so, is there a reason for the inconsistency?

I'm running Ubuntu 11.10 on an ext4 file system.

Best Answer

Many disks have a sector size of 512 bytes, meaning that any read or write on the disk transfers a whole 512-byte sector at a time. It is quite natural to design filesystems where a sector is not split between files (that would complicate the design and hurt performance); therefore filesystems tend to use 512-byte chunks for files. Hence traditional utilities such as ls and du indicate sizes in units of 512-byte chunks.

For humans, 512-byte units are not very meaningful. 1kB is the same order of magnitude and a lot more meaningful. A filesystem block (the smallest unit that a file is divided in) actually often consists of several sectors: 1kB, 2kB and 4kB are common filesystem block sizes; so the 512-byte unit is not strongly justified by the filesystem design, and there is no good reason other than tradition to use a 512-byte unit outside a disk driver at all.

So you have a tradition that doesn't have a lot going for it, and a more readable convention that's taking on. A bit like octal and hexadecimal: there isn't one that's right and one that's wrong, they're different ways of writing the same numbers.

Many tools have an option to select display units: ls --block-size=512 for GNU ls, setting POSIXLY_CORRECT=1 in the environment for GNU df and GNU du to get 512-byte units (or passing -k to force 1kB units). What the stat command in GNU coreutils exposes as the “block size” (the %B value) is an OS-dependant value of an internal interface; depending on the OS, it may or may not be related to a size used by the filesystem or disk code (it usually isn't — see Difference between block size and cluster size). On Linux, the value is 512, regardless of what any underlying driver is doing. The value of %B never matters, it's just a quirk that it exists at all.