]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/buffer: adjust align before calling posix_memalign()
authorIlya Dryomov <idryomov@gmail.com>
Tue, 4 May 2021 13:50:05 +0000 (15:50 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Sun, 9 May 2021 10:05:16 +0000 (12:05 +0200)
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 <idryomov@gmail.com>
(cherry picked from commit aa31ddf0e70b3b8ef8012e09cb3158f3db4dea1b)

Conflicts:
src/common/buffer.cc [ commit ea32d802031d ("common: drop
  sharing of buffer::raw outside bufferlist.") not in nautilus ]

src/common/buffer.cc

index 8caaae907aad29ab050c3a6d5e6e3e703728148e..4854e9b6f9619c7ff8398341370c1cf130473c18 100644 (file)
@@ -108,8 +108,8 @@ static ceph::spinlock debug_lock;
     static raw_combined *create(unsigned len,
                                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<unsigned>(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));
@@ -169,8 +169,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<unsigned>(_align, sizeof(void *));
 #ifdef DARWIN
       data = (char *) valloc(len);
 #else