From: Radoslaw Zarzynski Date: Mon, 19 Jul 2021 14:06:20 +0000 (+0000) Subject: common/bl: c_str() considers _carriage now. X-Git-Tag: v17.1.0~891^2~2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=578505c0c93b9dca029e0aa7f7ef3d6df8d598a6;p=ceph-ci.git 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 --- 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();