return seastar::now();
}
+seastar::future<std::vector<ghobject_t>, ghobject_t>
+CyanStore::list_objects(CollectionRef c,
+ const ghobject_t& start,
+ const ghobject_t& end,
+ uint64_t limit)
+{
+ logger().debug("{} {} {} {} {}",
+ __func__, c->cid, start, end, limit);
+ std::vector<ghobject_t> objects;
+ objects.reserve(limit);
+ ghobject_t next = ghobject_t::get_max();
+ for (const auto& [oid, obj] :
+ boost::make_iterator_range(c->object_map.lower_bound(start),
+ c->object_map.end())) {
+ std::ignore = obj;
+ if (oid >= end || objects.size() >= limit) {
+ next = oid;
+ break;
+ }
+ objects.push_back(oid);
+ }
+ return seastar::make_ready_future<std::vector<ghobject_t>, ghobject_t>(
+ std::move(objects), next);
+}
+
CyanStore::CollectionRef CyanStore::create_new_collection(const coll_t& cid)
{
auto c = new Collection{cid};
CollectionRef c,
const ghobject_t& oid,
std::vector<std::string>&& keys);
+ seastar::future<std::vector<ghobject_t>, ghobject_t> list_objects(
+ CollectionRef c,
+ const ghobject_t& start,
+ const ghobject_t& end,
+ uint64_t limit);
CollectionRef create_new_collection(const coll_t& cid);
CollectionRef open_collection(const coll_t& cid);
std::vector<coll_t> list_collections();
}
}
+using ceph::common::local_conf;
using recovery::AdvMap;
using recovery::ActMap;
using recovery::Initialize;
return backend->writefull(os, osd_op, txn);
case CEPH_OSD_OP_SETALLOCHINT:
return seastar::now();
+ case CEPH_OSD_OP_PGNLS:
+ return do_pgnls(osd_op.indata, os.oi.soid.get_namespace(), op.pgls.count)
+ .then([&osd_op](bufferlist bl) {
+ osd_op.outdata = std::move(bl);
+ return seastar::now();
+ });
default:
throw std::runtime_error(
fmt::format("op '{}' not supported", ceph_osd_op_name(op.op)));
}
}
+seastar::future<bufferlist> PG::do_pgnls(bufferlist& indata,
+ const std::string& nspace,
+ uint64_t limit)
+{
+ hobject_t lower_bound;
+ try {
+ ceph::decode(lower_bound, indata);
+ } catch (const buffer::error& e) {
+ throw std::invalid_argument("unable to decode PGNLS handle");
+ }
+ const auto pg_start = pgid.pgid.get_hobj_start();
+ const auto pg_end = pgid.pgid.get_hobj_end(pool.get_pg_num());
+ if (!(lower_bound.is_min() ||
+ lower_bound.is_max() ||
+ (lower_bound >= pg_start && lower_bound < pg_end))) {
+ // this should only happen with a buggy client.
+ throw std::invalid_argument("outside of PG bounds");
+ }
+ return backend->list_objects(lower_bound, limit).then(
+ [lower_bound, pg_end, nspace](auto objects, auto next) {
+ auto in_my_namespace = [&nspace](const hobject_t& o) {
+ if (o.get_namespace() == local_conf()->osd_hit_set_namespace) {
+ return false;
+ } else if (nspace == librados::all_nspaces) {
+ return true;
+ } else {
+ return o.get_namespace() == nspace;
+ }
+ };
+ pg_nls_response_t response;
+ boost::copy(objects |
+ boost::adaptors::filtered(in_my_namespace) |
+ boost::adaptors::transformed([](const hobject_t& o) {
+ return librados::ListObjectImpl{o.get_namespace(),
+ o.oid.name,
+ o.get_key()}; }),
+ std::back_inserter(response.entries));
+ response.handle = next.is_max() ? pg_end : next;
+ bufferlist bl;
+ encode(response, bl);
+ return seastar::make_ready_future<bufferlist>(std::move(bl));
+ });
+}
+
seastar::future<Ref<MOSDOpReply>> PG::do_osd_ops(Ref<MOSDOp> m)
{
return seastar::do_with(std::move(m), ceph::os::Transaction{},
ObjectState& os,
OSDOp& op,
ceph::os::Transaction& txn);
+ seastar::future<ceph::bufferlist> do_pgnls(ceph::bufferlist& indata,
+ const std::string& nspace,
+ uint64_t limit);
private:
const spg_t pgid;
#include "pg_backend.h"
#include <optional>
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/algorithm/copy.hpp>
#include <fmt/ostream.h>
#include <seastar/core/print.hh>
}
return seastar::now();
}
+
+seastar::future<std::vector<hobject_t>, hobject_t>
+PGBackend::list_objects(const hobject_t& start, uint64_t limit)
+{
+ auto gstart = start.is_min() ? ghobject_t{} : ghobject_t{start, 0, shard};
+ return store->list_objects(coll,
+ gstart,
+ ghobject_t::get_max(),
+ limit)
+ .then([this](std::vector<ghobject_t> gobjects, ghobject_t next) {
+ std::vector<hobject_t> objects;
+ boost::copy(gobjects |
+ boost::adaptors::filtered([](const ghobject_t& o) {
+ if (o.is_pgmeta()) {
+ return false;
+ } else if (o.hobj.is_temp()) {
+ return false;
+ } else {
+ return o.is_no_gen();
+ }
+ }) |
+ boost::adaptors::transformed([](const ghobject_t& o) {
+ return o.hobj;
+ }),
+ std::back_inserter(objects));
+ return seastar::make_ready_future<std::vector<hobject_t>, hobject_t>(
+ objects, next.hobj);
+ });
+}
cached_os_t&& os,
ceph::os::Transaction&& txn,
const MOSDOp& m);
+ seastar::future<std::vector<hobject_t>, hobject_t> list_objects(
+ const hobject_t& start,
+ uint64_t limit);
protected:
const shard_id_t shard;