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.
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 <jim@meyering.net>
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.
Comments
Post a Comment
https://gengwg.blogspot.com/