[Toybox] [landley/toybox] stat: block size differences (#41)
Rob Landley
rob at landley.net
Thu Aug 11 07:37:21 PDT 2016
On 08/11/2016 03:49 AM, Matthias Urhahn wrote:
> Toybox 0.7.1, Busybox 1.24.2
> On a Nexus5 at 6.0.
>
> Why is there a difference in blocksize?
>
> |root at hammerhead:/sdcard # busybox stat -c %B:%b:%o:%s
> twrp-3.0.0-0-hammerhead.img 512:28632:4096:14657536
> root at hammerhead:/sdcard # toybox stat -c %B:%b:%o:%s
> twrp-3.0.0-0-hammerhead.img 4096:28632:4096:14657536 |
>
> %B Bytes per block
In toybox, both %o and %B come from the stat() system call.
else if (type == 'B') out('u', stat->st_blksize);
} else if (type == 'o') out('u', stat->st_blksize);
I.E. we're telling you what the operating system told us (presumably
getting it from the filesystem driver).
A quick check shows busybox is printing a hardwired value for %B but the
stat value for %o:
} else if (m == 'B') {
strcat(pformat, "lu");
printf(pformat, (unsigned long) 512); //ST_NBLOCKSIZE
} else if (m == 'o') {
strcat(pformat, "lu");
printf(pformat, (unsigned long) statbuf->st_blksize);
I don't understand the point of printing a hardwired value for %B? FAT
block sizes vary from 512 bytes up to 65535k. ext2 can be 1k or 4k.
A few years ago hard drives went from 512 byte physical block to 4k,
which caused some problems because of longstanding assumptions:
https://lwn.net/Articles/322777/
https://lwn.net/Articles/377895/
And now the sectors are getting bigger:
https://lwn.net/Articles/582862/
Here's some articles about the damage conflicting block size assumptions
can do (data loss when an interrupted write changes stuff you didn't
think was being rewritten) and ways around it:
https://lwn.net/Articles/349970/
https://lwn.net/Articles/665299/
https://lwn.net/Articles/353411/
You shouldn't have to care about 90% of that (the OS handles it all for
you), but from my perspective having two ways to query block size would
be really nice if the OS gave me a way to determine the block size of
the physical media, as distinct from the block size of the filesystem.
Unfortunately, although it _seems_ like %B would be filesystem block
size and %o would be physical media block size, Linux doesn't give me a
way to query physical media block size that I've noticed. (I might be
able to beat it out of the mtd layer for some types of flash?)
> busybox says 512Byte while toybox says 4096Byte.
Busybox is returning a single hardwired answer.
That said, it looks like the Ubuntu version is also doing that. If %B
should always say "512" regardless of context, I can make it do that and
change the help text to say something like:
%B prints "512"
> 28632 Blocks * 512Byte = 14659584 Byte
> Which is a lot closer to the actual file size of 14657536 Byte (reported
> by both toybox&busybox).
More stat fields: %b is st_blocks and %s is st_size.
The stat(2) man page says that st_blocks is "number of 512B blocks
allocated" so %B is units for %b (and yes, it's a hardwired value). So
the help text should be something like:
%B units for %b (always 512)
> Other commands from both binaries also show a block size of 4096 Byte
> though.
The "man 1 stat" page says:
%B the size in bytes of each block reported by %b
The "man 2 stat" page says:
blkcnt_t st_blocks; /* number of 512B blocks allocated */
So yes, you've found an inconsistency and I should fix it. %B should
output a hardwired "512", busybox is correct here.
Thanks. Good catch,
Rob
More information about the Toybox
mailing list