From 578505c0c93b9dca029e0aa7f7ef3d6df8d598a6 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Mon, 19 Jul 2021 14:06:20 +0000 Subject: [PATCH] common/bl: c_str() considers _carriage now. It could be that `_carriage` points on empty bptr which is also stored in the `_buffers` container -- this happens when we'are trying to preserve the appendable space to not waste memory and avoid new allocation. Before the change this approach was imposing unncessary rebuilding on `c_str()`. Now we take into consideration the special case when a bufferlist has the extra, empty bptr at its end. Fixes: https://tracker.ceph.com/issues/51725 Signed-off-by: Radoslaw Zarzynski --- src/common/buffer.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 8ade26dc911..2b534402f6d 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1527,10 +1527,13 @@ static ceph::spinlock debug_lock; return nullptr; // no non-empty buffers } - auto iter = std::cbegin(_buffers); - ++iter; - - if (iter != std::cend(_buffers)) { + const auto second = std::next(std::cbegin(_buffers)); + // splice() tries to not waste our appendable space; to carry + // it an empty bptr is added at the end. we account for that. + const auto end = _carriage->length() == 0 && \ + _carriage == &_buffers.back() ? buffers_t::const_iterator(_carriage) + : std::cend(_buffers); + if (second != end) { rebuild(); } return _buffers.front().c_str(); -- 2.39.5