On 9/17/18 3:38 PM, Richard W.M. Jones wrote:
These are used at various places in the code already. This
refactoring simply moves them to a common header file and should have
no other effect.
---
common/include/rounding.h | 59 +++++++++++++++++++++++++++++++++++++
filters/cache/Makefile.am | 3 +-
filters/cache/cache.c | 2 +-
filters/cow/Makefile.am | 3 +-
filters/cow/cow.c | 2 +-
filters/truncate/truncate.c | 5 ++--
6 files changed, 68 insertions(+), 6 deletions(-)
+/* Round up i to next multiple of n (n must be a power of 2).
+ */
+#define ROUND_UP(i, n) ({ \
+ assert (is_power_of_2 (n)); \
+ ((i) + (n) - 1) & ~((n) - 1); \
+})
Potential bug: if n is 32-bit unsigned, but i is 64-bit, the bitmask on
the right half of & will be inappropriately truncated (no sign extension
is performed).
+
+/* Round down i to next multiple of n (n must be a power of 2).
+ */
+#define ROUND_DOWN(i, n) ({ \
+ assert (is_power_of_2 (n)); \
+ (i) & ~((n) - 1); \
+})
And again.
Also, ~((n)-1) is identical to -(n), if you want less typing (well, as
long as you assume twos-complements signed numbers, but that's pretty
safe to assume these days).
+
+/* Return n / d, rounding the result up to the next integer. */
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
This one should be okay, though.
+++ b/filters/truncate/truncate.c
@@ -46,6 +46,7 @@
#include "ispowerof2.h"
#include "iszero.h"
+#include "rounding.h"
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
@@ -157,9 +158,9 @@ truncate_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
if (truncate_size >= 0)
size = truncate_size;
if (round_up > 0)
- size = (size + round_up - 1) & ~(round_up - 1);
+ size = ROUND_UP (size, round_up);
if (round_down > 0)
- size &= ~(round_down - 1);
+ size = ROUND_DOWN (size, round_down);
Ouch - the bug was pre-existing. size is uint64_t, while
round_{up,down} is unsigned (and hence 32-bit), which means this failed
on sizes larger than 4G.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization:
qemu.org |
libvirt.org