file block size - difference between stat and ls

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.


After digging into the source code and POSIX standard, I would say the answer by @antje-m and @Gilles are mostly correct.

It's worth to quote the comment from POSIX.1-2008, as a summary:

The use of 512-byte units is historical practice and maintains compatibility with ls and other utilities in this volume of POSIX.1-2008. This does not mandate that the file system itself be based on 512-byte blocks. The -k option was added as a compromise measure. It was agreed by the standard developers that 512 bytes was the best default unit because of its complete historical consistency on System V (versus the mixed 512/1024-byte usage on BSD systems), and that a -k option to switch to 1024-byte units was a good compromise. Users who prefer the more logical 1024-byte quantity can easily alias df to df -k without breaking many historical scripts relying on the 512-byte units.

For the block size in ls -s:

The POSIX says that the default block size is implementation-defined, unless -k option is given.

The default block size implemented in GNU coreutils ls is defined in GNU gnulib: gnulib/lib/human.c

/* The default block size used for output.  This number may change in
   the future as disks get larger.  */
#ifndef DEFAULT_BLOCK_SIZE
# define DEFAULT_BLOCK_SIZE 1024
#endif

which comes from an old commit:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <[email protected]>
Date:   Mon Jun 29 15:23:04 1998 +0000

The commit message itself didn't say anything about the number 1024.

And note that the block size used in du and df is also 1024, ls just chose to consist with them. Although for du and df it is a confliction to the POSIX standard (so here the environment variable POSIXLY_CORRECT comes). This is seems a decision of the GNU team, see the wikipedia page POSIX about this controversy.

For the command stat.

It is not a part of POSIX standard, but the stat system call is. However the unit for block size is not standardized (sys_stat.h):

The unit for the st_blocks member of the stat structure is not defined within POSIX.1-2008.

The stat command simply displays the information provided by stat system call, and using 512 block size with few exception (they are non-Linux, e.g. HP-UX, IBM AIX etc. see the macros defined in gnulib/lib/stat-size.h).

So the number 512 is more a historical choice and a Linux convention.

The GNU coreutils (hence the ls command) is not a part of Linux kernel (hence the stat call), they are targeting different system aspect, GNU coreutils is more for human (easier to read), and Linux kernel for hardware abstract (hence closer to hardware).

Edit: the 4096 block size is the "IO block" size, the real physical block size is likely still 512 Byte as explained in this question.