#include <type_traits>
#include <variant>
+#include <fmt/format.h>
+#include <fmt/ostream.h>
+
#include <boost/asio/async_result.hpp>
#include <boost/asio/io_context.hpp>
IOContext();
explicit IOContext(std::int64_t pool);
- IOContext(std::int64_t _pool, std::string_view _ns);
- IOContext(std::int64_t _pool, std::string&& _ns);
+ IOContext(std::int64_t pool, std::string ns, std::string key = {});
~IOContext();
IOContext(const IOContext& rhs);
IOContext(IOContext&& rhs);
IOContext& operator =(IOContext&& rhs);
- std::int64_t pool() const;
- void pool(std::int64_t _pool);
+ std::int64_t get_pool() const;
+ void set_pool(std::int64_t _pool) &;
+ IOContext&& set_pool(std::int64_t _pool) &&;
- std::string_view ns() const;
- void ns(std::string_view _ns);
- void ns(std::string&& _ns);
+ std::string_view get_ns() const;
+ void set_ns(std::string ns) &;
+ IOContext&& set_ns(std::string ns) &&;
- std::optional<std::string_view> key() const;
- void key(std::string_view _key);
- void key(std::string&& _key);
- void clear_key();
+ std::string_view get_key() const;
+ void set_key(std::string key) &;
+ IOContext&& set_key(std::string key) &&;
- std::optional<std::int64_t> hash() const;
- void hash(std::int64_t _hash);
- void clear_hash();
+ std::int64_t get_hash() const;
+ void set_hash(std::int64_t hash) &;
+ IOContext&& set_hash(std::int64_t hash) &&;
- std::optional<std::uint64_t> read_snap() const;
- void read_snap(std::optional<std::uint64_t> _snapid);
+ std::uint64_t get_read_snap() const;
+ void set_read_snap(std::uint64_t snapid) &;
+ IOContext&& set_read_snap(std::uint64_t snapid) &&;
// I can't actually move-construct here since snapid_t is its own
// separate class type, not an alias.
std::optional<
std::pair<std::uint64_t,
- std::vector<std::uint64_t>>> write_snap_context() const;
- void write_snap_context(std::optional<
- std::pair<std::uint64_t,
- std::vector<std::uint64_t>>> snapc);
-
- bool full_try() const;
- void full_try(bool _full_try);
+ std::vector<std::uint64_t>>> get_write_snap_context() const;
+ void set_write_snap_context(
+ std::optional<std::pair<std::uint64_t,
+ std::vector<std::uint64_t>>> snapc) &;
+ IOContext&& set_write_snap_context(
+ std::optional<std::pair<std::uint64_t,
+ std::vector<std::uint64_t>>> snapc) &&;
+
+ bool get_full_try() const;
+ void set_full_try(bool full_try) &;
+ IOContext&& set_full_try(bool full_try) &&;
friend std::ostream& operator <<(std::ostream& m, const IOContext& o);
friend bool operator <(const IOContext& lhs, const IOContext& rhs);
std::aligned_storage_t<impl_size> impl;
};
-inline constexpr std::string_view all_nspaces("\001");
+inline const std::string all_nspaces("\001");
enum class cmpxattr_op : std::uint8_t {
eq = 1,
};
} // namespace std
+#if FMT_VERSION >= 90000
+template<> struct fmt::formatter<neorados::Object> : fmt::ostream_formatter {};
+template<> struct fmt::formatter<neorados::IOContext>
+ : fmt::ostream_formatter {};
+#endif // FMT_VERSION
+
#endif // NEORADOS_RADOS_HPP
auto ctx = std::make_shared<neorados::IOContext>(
data_ctx.get_id(), data_ctx.get_namespace());
if (snap_id != CEPH_NOSNAP) {
- ctx->read_snap(snap_id);
+ ctx->set_read_snap(snap_id);
}
if (!snapc.snaps.empty()) {
- ctx->write_snap_context(
+ ctx->set_write_snap_context(
{{snapc.seq, {snapc.snaps.begin(), snapc.snaps.end()}}});
}
if (data_ctx.get_pool_full_try()) {
- ctx->full_try(true);
+ ctx->set_full_try(true);
}
// atomically reset the data IOContext to new version
m_image_ctx->image_lock.lock_shared();
auto rd = m_object_cacher->prepare_read(
- io_context->read_snap().value_or(CEPH_NOSNAP), bl, op_flags);
+ io_context->get_read_snap(), bl, op_flags);
m_image_ctx->image_lock.unlock_shared();
uint64_t off = 0;
}
SnapContext snapc;
- if (io_context->write_snap_context()) {
- auto write_snap_context = *io_context->write_snap_context();
+ if (io_context->get_write_snap_context()) {
+ auto write_snap_context = *io_context->get_write_snap_context();
snapc = SnapContext(write_snap_context.first,
{write_snap_context.second.begin(),
write_snap_context.second.end()});
auto io_context = m_ictx->duplicate_data_io_context();
if (snapid != CEPH_NOSNAP) {
- io_context->read_snap(snapid);
+ io_context->set_read_snap(snapid);
}
// extract the embedded RBD read flags from the op_flags
auto io_context = m_ictx->duplicate_data_io_context();
if (!snapc.empty()) {
- io_context->write_snap_context(
+ io_context->set_write_snap_context(
{{snapc.seq, {snapc.snaps.begin(), snapc.snaps.end()}}});
}
m_cache_client->lookup_object(m_image_ctx->data_ctx.get_namespace(),
m_image_ctx->data_ctx.get_id(),
- io_context->read_snap().value_or(CEPH_NOSNAP),
+ io_context->get_read_snap(),
m_image_ctx->layout.object_size,
oid, std::move(ctx));
return true;
on_dispatched->complete(r);
});
m_plugin_api.read_parent(m_image_ctx, object_no, extents,
- io_context->read_snap().value_or(CEPH_NOSNAP),
+ io_context->get_read_snap(),
parent_trace, ctx);
return;
}
auto cct = m_image_ctx->cct;
ldout(cct, 20) << "image_extents=" << image_extents << dendl;
- if (io_context->read_snap().value_or(CEPH_NOSNAP) != CEPH_NOSNAP) {
+ if (io_context->get_read_snap() != CEPH_NOSNAP) {
return false;
}
if (r == -ENOENT && !disable_read_from_parent) {
io::util::read_parent<I>(
image_ctx, object_no, extents,
- io_context->read_snap().value_or(CEPH_NOSNAP),
+ io_context->get_read_snap(),
parent_trace, this);
} else {
complete(r);
}
auto io_context = m_src_image_ctx->duplicate_data_io_context();
- io_context->read_snap(index.second);
+ io_context->set_read_snap(index.second);
io::Extents image_extents{read_op.image_interval.begin(),
read_op.image_interval.end()};
ldout(cct, 20) << "copyup with empty snapshot context" << dendl;
auto copyup_io_context = *io_context;
- copyup_io_context.write_snap_context({});
+ copyup_io_context.set_write_snap_context({});
m_image_ctx->rados_api.execute(
object, copyup_io_context, std::move(copyup_op),
inline bool is_copy_on_read(I *ictx, const IOContext& io_context) {
std::shared_lock image_locker{ictx->image_lock};
return (ictx->clone_copy_on_read && !ictx->read_only &&
- io_context->read_snap().value_or(CEPH_NOSNAP) == CEPH_NOSNAP &&
+ io_context->get_read_snap() == CEPH_NOSNAP &&
(ictx->exclusive_lock == nullptr ||
ictx->exclusive_lock->is_lock_owner()));
}
uint64_t raw_overlap;
int r = m_ictx->get_parent_overlap(
- m_io_context->read_snap().value_or(CEPH_NOSNAP), &raw_overlap);
+ m_io_context->get_read_snap(), &raw_overlap);
if (r < 0) {
// NOTE: it's possible for a snapshot to be deleted while we are
// still reading from it
I *image_ctx = this->m_ictx;
std::shared_lock image_locker{image_ctx->image_lock};
- auto read_snap_id = this->m_io_context->read_snap().value_or(CEPH_NOSNAP);
+ auto read_snap_id = this->m_io_context->get_read_snap();
if (read_snap_id == image_ctx->snap_id &&
image_ctx->object_map != nullptr &&
!image_ctx->object_map->object_may_exist(this->m_object_no)) {
io::util::read_parent<I>(
image_ctx, this->m_object_no, this->m_extents,
- this->m_io_context->read_snap().value_or(CEPH_NOSNAP), this->m_trace,
+ this->m_io_context->get_read_snap(), this->m_trace,
ctx);
}
if (!this->has_parent() ||
(m_full_object &&
- !this->m_io_context->write_snap_context() &&
+ !this->m_io_context->get_write_snap_context() &&
!is_post_copyup_write_required())) {
m_copyup_enabled = false;
}
neorados::WriteOp write_op;
if (m_copyup_enabled) {
if (m_guarding_migration_write) {
- auto snap_seq = (this->m_io_context->write_snap_context() ?
- this->m_io_context->write_snap_context()->first : 0);
+ auto snap_seq = (this->m_io_context->get_write_snap_context() ?
+ this->m_io_context->get_write_snap_context()->first : 0);
ldout(image_ctx->cct, 20) << "guarding write: snap_seq=" << snap_seq
<< dendl;
m_object_extents(std::move(object_extents)),
m_snap_ids(std::move(snap_ids)), m_list_snaps_flags(list_snaps_flags),
m_snapshot_delta(snapshot_delta) {
- this->m_io_context->read_snap(CEPH_SNAPDIR);
+ this->m_io_context->set_read_snap(CEPH_SNAPDIR);
}
template <typename I>
ldout(cct, 20) << dendl;
*dispatch_result = io::DISPATCH_RESULT_COMPLETE;
- return m_format->read(aio_comp, io_context->read_snap().value_or(CEPH_NOSNAP),
+ return m_format->read(aio_comp, io_context->get_read_snap(),
std::move(image_extents), std::move(read_result),
op_flags, read_flags, parent_trace);
}
new (&impl) IOContextImpl();
}
-IOContext::IOContext(std::int64_t _pool) : IOContext() {
- pool(_pool);
+IOContext::IOContext(std::int64_t pool) : IOContext() {
+ set_pool(pool);
}
-IOContext::IOContext(std::int64_t _pool, std::string_view _ns)
+IOContext::IOContext(std::int64_t pool, std::string ns, std::string key)
: IOContext() {
- pool(_pool);
- ns(_ns);
-}
-
-IOContext::IOContext(std::int64_t _pool, std::string&& _ns)
- : IOContext() {
- pool(_pool);
- ns(std::move(_ns));
+ set_pool(pool);
+ set_ns(std::move(ns));
+ set_key(std::move(key));
}
IOContext::~IOContext() {
return *this;
}
-std::int64_t IOContext::pool() const {
+std::int64_t IOContext::get_pool() const {
return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.pool;
}
-void IOContext::pool(std::int64_t _pool) {
- reinterpret_cast<IOContextImpl*>(&impl)->oloc.pool = _pool;
+void IOContext::set_pool(std::int64_t pool) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->oloc.pool = pool;
}
-std::string_view IOContext::ns() const {
- return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.nspace;
+IOContext&& IOContext::set_pool(std::int64_t pool) && {
+ set_pool(pool);
+ return std::move(*this);
}
-void IOContext::ns(std::string_view _ns) {
- reinterpret_cast<IOContextImpl*>(&impl)->oloc.nspace = _ns;
+std::string_view IOContext::get_ns() const {
+ return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.nspace;
}
-void IOContext::ns(std::string&& _ns) {
- reinterpret_cast<IOContextImpl*>(&impl)->oloc.nspace = std::move(_ns);
+void IOContext::set_ns(std::string ns) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->oloc.nspace = std::move(ns);
}
-std::optional<std::string_view> IOContext::key() const {
- auto& oloc = reinterpret_cast<const IOContextImpl*>(&impl)->oloc;
- if (oloc.key.empty())
- return std::nullopt;
- else
- return std::string_view(oloc.key);
+IOContext&& IOContext::set_ns(std::string ns) && {
+ set_ns(std::move(ns));
+ return std::move(*this);
}
-void IOContext::key(std::string_view _key) {
- auto& oloc = reinterpret_cast<IOContextImpl*>(&impl)->oloc;
- oloc.hash = -1;
- oloc.key = _key;
+std::string_view IOContext::get_key() const {
+ return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.key;
}
-void IOContext::key(std::string&&_key) {
+void IOContext::set_key(std::string key) & {
auto& oloc = reinterpret_cast<IOContextImpl*>(&impl)->oloc;
oloc.hash = -1;
- oloc.key = std::move(_key);
+ oloc.key = std::move(key);
}
-void IOContext::clear_key() {
- auto& oloc = reinterpret_cast<IOContextImpl*>(&impl)->oloc;
- oloc.hash = -1;
- oloc.key.clear();
+IOContext&& IOContext::set_key(std::string key) && {
+ set_key(std::move(key));
+ return std::move(*this);
}
-std::optional<std::int64_t> IOContext::hash() const {
- auto& oloc = reinterpret_cast<const IOContextImpl*>(&impl)->oloc;
- if (oloc.hash < 0)
- return std::nullopt;
- else
- return oloc.hash;
+std::int64_t IOContext::get_hash() const {
+ return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.hash;
}
-void IOContext::hash(std::int64_t _hash) {
+void IOContext::set_hash(std::int64_t hash) & {
auto& oloc = reinterpret_cast<IOContextImpl*>(&impl)->oloc;
- oloc.hash = _hash;
+ oloc.hash = hash;
oloc.key.clear();
}
-void IOContext::clear_hash() {
- auto& oloc = reinterpret_cast<IOContextImpl*>(&impl)->oloc;
- oloc.hash = -1;
- oloc.key.clear();
+IOContext&& IOContext::set_hash(std::int64_t hash) && {
+ set_hash(hash);
+ return std::move(*this);
}
+std::uint64_t IOContext::get_read_snap() const {
+ return reinterpret_cast<const IOContextImpl*>(&impl)->snap_seq;
+}
-std::optional<std::uint64_t> IOContext::read_snap() const {
- auto& snap_seq = reinterpret_cast<const IOContextImpl*>(&impl)->snap_seq;
- if (snap_seq == CEPH_NOSNAP)
- return std::nullopt;
- else
- return snap_seq;
+void IOContext::set_read_snap(std::uint64_t snapid) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->snap_seq = snapid;
}
-void IOContext::read_snap(std::optional<std::uint64_t> _snapid) {
- auto& snap_seq = reinterpret_cast<IOContextImpl*>(&impl)->snap_seq;
- snap_seq = _snapid.value_or(CEPH_NOSNAP);
+
+IOContext&& IOContext::set_read_snap(std::uint64_t snapid) && {
+ set_read_snap(snapid);
+ return std::move(*this);
}
-std::optional<
- std::pair<std::uint64_t,
- std::vector<std::uint64_t>>> IOContext::write_snap_context() const {
+std::optional<std::pair<std::uint64_t, std::vector<std::uint64_t>>>
+IOContext::get_write_snap_context() const {
auto& snapc = reinterpret_cast<const IOContextImpl*>(&impl)->snapc;
if (snapc.empty()) {
return std::nullopt;
}
}
-void IOContext::write_snap_context(
- std::optional<std::pair<std::uint64_t, std::vector<std::uint64_t>>> _snapc) {
+void IOContext::set_write_snap_context(
+ std::optional<std::pair<std::uint64_t,
+ std::vector<std::uint64_t>>> _snapc) & {
auto& snapc = reinterpret_cast<IOContextImpl*>(&impl)->snapc;
if (!_snapc) {
snapc.clear();
}
}
-bool IOContext::full_try() const {
+IOContext&& IOContext::set_write_snap_context(
+ std::optional<std::pair<std::uint64_t,
+ std::vector<std::uint64_t>>> snapc) && {
+ set_write_snap_context(std::move(snapc));
+ return std::move(*this);
+}
+
+bool IOContext::get_full_try() const {
const auto ioc = reinterpret_cast<const IOContextImpl*>(&impl);
return (ioc->extra_op_flags & CEPH_OSD_FLAG_FULL_TRY) != 0;
}
-void IOContext::full_try(bool _full_try) {
+void IOContext::set_full_try(bool full_try) & {
auto ioc = reinterpret_cast<IOContextImpl*>(&impl);
- if (_full_try) {
+ if (full_try) {
ioc->extra_op_flags |= CEPH_OSD_FLAG_FULL_TRY;
} else {
ioc->extra_op_flags &= ~CEPH_OSD_FLAG_FULL_TRY;
}
}
+IOContext&& IOContext::set_full_try(bool full_try) && {
+ set_full_try(full_try);
+ return std::move(*this);
+}
+
bool operator <(const IOContext& lhs, const IOContext& rhs) {
const auto l = reinterpret_cast<const IOContextImpl*>(&lhs.impl);
const auto r = reinterpret_cast<const IOContextImpl*>(&rhs.impl);
}
librados::TestIoCtxImpl* get_io_ctx(const IOContext& ioc) {
- int64_t pool_id = ioc.pool();
- std::string ns = std::string{ioc.ns()};
+ int64_t pool_id = ioc.get_pool();
+ std::string ns = std::string{ioc.get_ns()};
auto lock = std::scoped_lock{mutex};
auto key = make_pair(pool_id, ns);
new (&impl) IOContextImpl(*reinterpret_cast<const IOContextImpl*>(&rhs.impl));
}
-IOContext::IOContext(int64_t _pool, std::string&& _ns)
+IOContext::IOContext(int64_t pool, std::string ns, std::string key)
: IOContext() {
- pool(_pool);
- ns(std::move(_ns));
+ set_pool(pool);
+ set_ns(std::move(ns));
+ set_key(std::move(key));
}
IOContext::~IOContext() {
reinterpret_cast<IOContextImpl*>(&impl)->~IOContextImpl();
}
-std::int64_t IOContext::pool() const {
+std::int64_t IOContext::get_pool() const {
return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.pool;
}
-void IOContext::pool(std::int64_t _pool) {
- reinterpret_cast<IOContextImpl*>(&impl)->oloc.pool = _pool;
+void IOContext::set_pool(std::int64_t pool) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->oloc.pool = pool;
}
-std::string_view IOContext::ns() const {
+IOContext&& IOContext::set_pool(std::int64_t pool) && {
+ set_pool(pool);
+ return std::move(*this);
+}
+
+std::string_view IOContext::get_ns() const {
return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.nspace;
}
-void IOContext::ns(std::string&& _ns) {
- reinterpret_cast<IOContextImpl*>(&impl)->oloc.nspace = std::move(_ns);
+void IOContext::set_ns(std::string ns) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->oloc.nspace = std::move(ns);
}
-std::optional<std::uint64_t> IOContext::read_snap() const {
- auto& snap_seq = reinterpret_cast<const IOContextImpl*>(&impl)->snap_seq;
- if (snap_seq == CEPH_NOSNAP)
- return std::nullopt;
- else
- return snap_seq;
+IOContext&& IOContext::set_ns(std::string ns) && {
+ set_ns(std::move(ns));
+ return std::move(*this);
+}
+
+std::string_view IOContext::get_key() const {
+ return reinterpret_cast<const IOContextImpl*>(&impl)->oloc.key;
+}
+
+void IOContext::set_key(std::string key) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->oloc.key = std::move(key);
}
-void IOContext::read_snap(std::optional<std::uint64_t> _snapid) {
- auto& snap_seq = reinterpret_cast<IOContextImpl*>(&impl)->snap_seq;
- snap_seq = _snapid.value_or(CEPH_NOSNAP);
+
+IOContext&& IOContext::set_key(std::string key) && {
+ set_key(std::move(key));
+ return std::move(*this);
}
+std::uint64_t IOContext::get_read_snap() const {
+ return reinterpret_cast<const IOContextImpl*>(&impl)->snap_seq;
+}
+
+void IOContext::set_read_snap(std::uint64_t snapid) & {
+ reinterpret_cast<IOContextImpl*>(&impl)->snap_seq = snapid;
+}
+IOContext&& IOContext::set_read_snap(std::uint64_t snapid) && {
+ set_read_snap(snapid);
+ return std::move(*this);
+}
+
+
std::optional<
std::pair<std::uint64_t,
- std::vector<std::uint64_t>>> IOContext::write_snap_context() const {
+ std::vector<std::uint64_t>>> IOContext::get_write_snap_context() const {
auto& snapc = reinterpret_cast<const IOContextImpl*>(&impl)->snapc;
if (snapc.empty()) {
return std::nullopt;
}
}
-void IOContext::write_snap_context(
- std::optional<std::pair<std::uint64_t, std::vector<std::uint64_t>>> _snapc) {
+void IOContext::set_write_snap_context(
+ std::optional<std::pair<std::uint64_t, std::vector<std::uint64_t>>> _snapc) & {
auto& snapc = reinterpret_cast<IOContextImpl*>(&impl)->snapc;
if (!_snapc) {
snapc.clear();
}
}
-void IOContext::full_try(bool _full_try) {
+void IOContext::set_full_try(bool _full_try) & {
// no-op
}
auto ops = *reinterpret_cast<librados::TestObjectOperationImpl**>(&op.impl);
- auto snap_id = CEPH_NOSNAP;
- auto opt_snap_id = ioc.read_snap();
- if (opt_snap_id) {
- snap_id = *opt_snap_id;
- }
+ auto snap_id = ioc.get_read_snap();
auto completion = create_aio_completion(std::move(c));
auto r = io_ctx->aio_operate_read(std::string{o}, *ops, completion, 0U, bl,
auto ops = *reinterpret_cast<librados::TestObjectOperationImpl**>(&op.impl);
SnapContext snapc;
- auto opt_snapc = ioc.write_snap_context();
+ auto opt_snapc = ioc.get_write_snap_context();
if (opt_snapc) {
snapc.seq = opt_snapc->first;
snapc.snaps.assign(opt_snapc->second.begin(), opt_snapc->second.end());
MATCHER_P2(IsRead, snap_id, image_interval, "") {
auto req = boost::get<io::ImageDispatchSpec::Read>(&arg->request);
if (req == nullptr ||
- arg->io_context->read_snap().value_or(CEPH_NOSNAP) != snap_id) {
+ arg->io_context->get_read_snap() != snap_id) {
return false;
}
void expect_list_snaps(MockTestImageCtx &mock_image_ctx,
const librados::snap_set_t& snap_set, int r) {
auto io_context = *mock_image_ctx.get_data_io_context();
- io_context.read_snap(CEPH_SNAPDIR);
+ io_context.set_read_snap(CEPH_SNAPDIR);
auto& mock_io_ctx = librados::get_mock_io_ctx(mock_image_ctx.rados_api,
io_context);
EXPECT_CALL(mock_io_ctx, list_snaps(_, _))
auto ctx = std::make_shared<neorados::IOContext>(
data_ctx.get_id(), data_ctx.get_namespace());
if (snap_id != CEPH_NOSNAP) {
- ctx->read_snap(snap_id);
+ ctx->set_read_snap(snap_id);
}
if (!snapc.snaps.empty()) {
- ctx->write_snap_context(
+ ctx->set_write_snap_context(
{{snapc.seq, {snapc.snaps.begin(), snapc.snaps.end()}}});
}
return ctx;
std::cout << "begin = " << b.to_str() << std::endl;
std::cout << "end = " << e.to_str() << std::endl;
- R::IOContext pool{p, R::all_nspaces};
try {
- auto [v, next] = r.enumerate_objects(pool, b, e, 1000, {}, ca::use_blocked);
+ auto [v, next] = r.enumerate_objects({p, R::all_nspaces}, b, e, 1000, {},
+ ca::use_blocked);
std::cout << "Got " << v.size() << " entries." << std::endl;
std::cout << "next cursor = " << next.to_str() << std::endl;
void ls(R::RADOS& r, const std::vector<std::string>& p, s::yield_context y)
{
const auto& pname = p[0];
- auto pool = lookup_pool(r, pname, y);
- pool.ns(R::all_nspaces);
+ const auto pool = lookup_pool(r, pname, y).set_ns(R::all_nspaces);
std::vector<R::Entry> ls;
R::Cursor next = R::Cursor::begin();
throw bs::system_error(
ec,
fmt::format("when reading from object '{}' in pool '{}'",
- obj, pool.pool()));
+ obj, pool));
off += bl.length();
bl.write_stream(std::cout);