From 846ac007840aa8e01a45343bb8f76c1ae6e9f578 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 4 May 2021 15:50:05 +0200 Subject: [PATCH] common/buffer: adjust align before calling posix_memalign() posix_memalign() requires alignment argument to be a multiple of sizeof(void *). Since it is an implementation detail of buffer, it needs to be adjusted there -- buffer consumers have no way of knowing that passing e.g. align == 4 is incorrect. One place already does the adjustment, but only for align == 0. The other just asserts. Fix both and remove the "power of two" assertion. Let posix_memalign() return EINVAL and handle that by throwing buffer::bad_alloc, as expected by the consumers. Fixes: https://tracker.ceph.com/issues/50646 Signed-off-by: Ilya Dryomov (cherry picked from commit aa31ddf0e70b3b8ef8012e09cb3158f3db4dea1b) --- src/common/buffer.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 8d7583e7adb06..406ca24a4a63c 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -99,8 +99,8 @@ static ceph::spinlock debug_lock; unsigned align, int mempool = mempool::mempool_buffer_anon) { - if (!align) - align = sizeof(size_t); + // posix_memalign() requires a multiple of sizeof(void *) + align = std::max(align, sizeof(void *)); size_t rawlen = round_up_to(sizeof(buffer::raw_combined), alignof(buffer::raw_combined)); size_t datalen = round_up_to(len, alignof(buffer::raw_combined)); @@ -161,8 +161,8 @@ static ceph::spinlock debug_lock; MEMPOOL_CLASS_HELPERS(); raw_posix_aligned(unsigned l, unsigned _align) : raw(l) { - align = _align; - ceph_assert((align >= sizeof(void *)) && (align & (align - 1)) == 0); + // posix_memalign() requires a multiple of sizeof(void *) + align = std::max(_align, sizeof(void *)); #ifdef DARWIN data = (char *) valloc(len); #else -- 2.39.5