]> git.baikalelectronics.ru Git - kernel.git/commit
sd, mmc, virtio_blk, string_helpers: fix block size units
authorJames Bottomley <JBottomley@Odin.com>
Fri, 6 Mar 2015 02:47:01 +0000 (18:47 -0800)
committerJames Bottomley <JBottomley@Odin.com>
Fri, 10 Apr 2015 23:27:48 +0000 (16:27 -0700)
commit757e6d5ca592f9cfcd4c5745f635d8ba0156cf7d
tree75a15cd66637d33e6d8e6e0c6cdd67e44790b376
parente38f3793e5724aee98b1ffbb78a1ab4df151cec5
sd, mmc, virtio_blk, string_helpers: fix block size units

The current string_get_size() overflows when the device size goes over
2^64 bytes because the string helper routine computes the suffix from
the size in bytes.  However, the entirety of Linux thinks in terms of
blocks, not bytes, so this will artificially induce an overflow on very
large devices.  Fix this by making the function string_get_size() take
blocks and the block size instead of bytes.  This should allow us to
keep working until the current SCSI standard overflows.

Also fix virtio_blk and mmc (both of which were also artificially
multiplying by the block size to pass a byte side to string_get_size()).

The mathematics of this is pretty simple:  we're taking a product of
size in blocks (S) and block size (B) and trying to re-express this in
exponential form: S*B = R*N^E (where N, the exponent is either 1000 or
1024) and R < N.  Mathematically, S = RS*N^ES and B=RB*N^EB, so if RS*RB
< N it's easy to see that S*B = RS*RB*N^(ES+EB).  However, if RS*BS > N,
we can see that this can be re-expressed as RS*BS = R*N (where R =
RS*BS/N < N) so the whole exponent becomes R*N^(ES+EB+1)

[jejb: fix incorrect 32 bit do_div spotted by kbuild test robot <fengguang.wu@intel.com>]
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
drivers/block/virtio_blk.c
drivers/mmc/card/block.c
drivers/scsi/sd.c
include/linux/string_helpers.h
lib/string_helpers.c