summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Spray <john.spray@redhat.com>2015-08-17 20:40:46 +0200
committerJohn Spray <john.spray@redhat.com>2015-12-03 15:57:39 +0100
commit138f58493715e386929f152424b70df37843541b (patch)
treee7b437714139a63f85c5e687024a571197d7183a /src
parentosd: set handle to start of next PG on pgnls end of pg (diff)
downloadceph-138f58493715e386929f152424b70df37843541b.tar.xz
ceph-138f58493715e386929f152424b70df37843541b.zip
osdc/Objecter: new-style pgls
Signed-off-by: John Spray <john.spray@redhat.com> Signed-off-by: Sage Weil <sage@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/osdc/Objecter.cc195
-rw-r--r--src/osdc/Objecter.h25
2 files changed, 217 insertions, 3 deletions
diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc
index ac060484349..852ec6ab0ed 100644
--- a/src/osdc/Objecter.cc
+++ b/src/osdc/Objecter.cc
@@ -2184,9 +2184,9 @@ ceph_tid_t Objecter::_op_submit(Op *op, RWLock::Context& lc)
_send_op_account(op);
// send?
- ldout(cct, 10) << "_op_submit oid " << op->target.base_oid
- << " " << op->target.base_oloc << " " << op->target.target_oloc
- << " " << op->ops << " tid " << op->tid
+ ldout(cct, 10) << "_op_submit oid '" << op->target.base_oid
+ << "' '" << op->target.base_oloc << "' '" << op->target.target_oloc
+ << "' " << op->ops << " tid " << op->tid
<< " osd." << (!s->is_homeless() ? s->osd : -1)
<< dendl;
@@ -4710,3 +4710,192 @@ void Objecter::set_epoch_barrier(epoch_t epoch)
}
}
+
+
+hobject_t Objecter::enumerate_objects_begin()
+{
+ return hobject_t();
+}
+
+hobject_t Objecter::enumerate_objects_end()
+{
+ return hobject_t::get_max();
+}
+
+struct C_EnumerateReply : public Context {
+ bufferlist bl;
+
+ Objecter *objecter;
+ hobject_t *next;
+ std::list<librados::ListObjectImpl> *result;
+ const hobject_t end;
+ const int64_t pool_id;
+ Context *on_finish;
+
+ epoch_t epoch;
+ int budget;
+
+ C_EnumerateReply(Objecter *objecter_, hobject_t *next_,
+ std::list<librados::ListObjectImpl> *result_,
+ const hobject_t end_, const int64_t pool_id_, Context *on_finish_) :
+ objecter(objecter_), next(next_), result(result_),
+ end(end_), pool_id(pool_id_), on_finish(on_finish_),
+ epoch(0), budget(0)
+ {}
+
+ void finish(int r) {
+ objecter->_enumerate_reply(
+ bl, r, end, pool_id, budget, epoch, result, next, on_finish);
+ }
+};
+
+void Objecter::enumerate_objects(
+ int64_t pool_id,
+ const std::string &ns,
+ const hobject_t &start,
+ const hobject_t &end,
+ const uint32_t max,
+ std::list<librados::ListObjectImpl> *result,
+ hobject_t *next,
+ Context *on_finish)
+{
+ assert(result);
+
+ if (!end.is_max() && cmp_bitwise(start, end) > 0) {
+ lderr(cct) << __func__ << ": start " << start << " > end " << end << dendl;
+ on_finish->complete(-EINVAL);
+ return;
+ }
+
+ if (max < 1) {
+ lderr(cct) << __func__ << ": result size may not be zero" << dendl;
+ on_finish->complete(-EINVAL);
+ return;
+ }
+
+ if (start.is_max()) {
+ on_finish->complete(0);
+ return;
+ }
+
+ // Map `start` to a PG
+ rwlock.get_read();
+ assert(osdmap->get_epoch());
+ if (!osdmap->test_flag(CEPH_OSDMAP_SORTBITWISE)) {
+ rwlock.unlock();
+ lderr(cct) << __func__ << ": SORTBITWISE cluster flag not set" << dendl;
+ on_finish->complete(-EOPNOTSUPP);
+ return;
+ }
+ const pg_pool_t *p = osdmap->get_pg_pool(pool_id);
+ int pg_num;
+ if (!p) {
+ lderr(cct) << __func__ << ": pool " << pool_id << " DNE in"
+ "osd epoch " << osdmap->get_epoch() << dendl;
+ rwlock.unlock();
+ on_finish->complete(-ENOENT);
+ } else {
+ pg_num = p->raw_hash_to_pg(start.get_hash());
+ rwlock.unlock();
+ }
+
+ ldout(cct, 20) << __func__ << ": start=" << start << " end=" << end
+ << " to pg " << pg_num << dendl;
+
+ // Stash completion state
+ C_EnumerateReply *on_ack = new C_EnumerateReply(
+ this, next, result, end, pool_id, on_finish);
+
+ // Construct pgls operation
+ bufferlist filter; // FIXME pass in?
+
+ ObjectOperation op;
+ op.pg_nls(max, filter, start, 0);
+
+ // Issue. See you later in _enumerate_reply
+ object_locator_t oloc(pool_id, ns);
+ pg_read(pg_num, oloc, op,
+ &on_ack->bl, 0, on_ack, &on_ack->epoch, &on_ack->budget);
+}
+
+void Objecter::_enumerate_reply(
+ bufferlist &bl,
+ int r,
+ const hobject_t &end,
+ const int64_t pool_id,
+ int budget,
+ epoch_t reply_epoch,
+ std::list<librados::ListObjectImpl> *result,
+ hobject_t *next,
+ Context *on_finish)
+{
+ if (budget > 0) {
+ put_op_budget_bytes(budget);
+ }
+
+ if (r < 0) {
+ ldout(cct, 4) << __func__ << ": remote error " << r << dendl;
+ on_finish->complete(r);
+ }
+
+ assert(next != NULL);
+
+ // Decode the results
+ bufferlist::iterator iter = bl.begin();
+ pg_nls_response_t response;
+
+ // XXX extra_info doesn't seem used anywhere?
+ bufferlist extra_info;
+ ::decode(response, iter);
+ if (!iter.end()) {
+ ::decode(extra_info, iter);
+ }
+
+ ldout(cct, 10) << __func__ << ": got " << response.entries.size()
+ << " handle " << response.handle
+ << " reply_epoch " << reply_epoch << dendl;
+ ldout(cct, 20) << __func__ << ": response.entries.size "
+ << response.entries.size() << ", response.entries "
+ << response.entries << dendl;
+ if (cmp_bitwise(response.handle, end) <= 0) {
+ *next = response.handle;
+ } else {
+ ldout(cct, 10) << __func__ << ": adjusted next down to end " << end << dendl;
+ *next = end;
+
+ // drop anything after 'end'
+ rwlock.get_read();
+ const pg_pool_t *pool = osdmap->get_pg_pool(pool_id);
+ while (!response.entries.empty()) {
+ uint32_t hash = response.entries.back().locator.empty() ?
+ pool->hash_key(response.entries.back().oid,
+ response.entries.back().nspace) :
+ pool->hash_key(response.entries.back().locator,
+ response.entries.back().nspace);
+ hobject_t last(response.entries.back().oid,
+ response.entries.back().locator,
+ CEPH_NOSNAP,
+ hash,
+ pool_id,
+ response.entries.back().nspace);
+ if (cmp_bitwise(last, end) < 0)
+ break;
+ ldout(cct, 20) << __func__ << " dropping item " << last
+ << " >= end " << end << dendl;
+ response.entries.pop_back();
+ }
+ rwlock.put_read();
+ }
+ if (!response.entries.empty()) {
+ result->merge(response.entries);
+ }
+
+ // release the listing context's budget once all
+ // OPs (in the session) are finished
+#if 0
+ put_nlist_context_budget(list_context);
+#endif
+ on_finish->complete(r);
+ return;
+}
+
diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h
index ac09e70b7dd..7147008adfa 100644
--- a/src/osdc/Objecter.h
+++ b/src/osdc/Objecter.h
@@ -2525,6 +2525,31 @@ public:
void list_objects(ListContext *p, Context *onfinish);
uint32_t list_objects_seek(ListContext *p, uint32_t pos);
+ hobject_t enumerate_objects_begin();
+ hobject_t enumerate_objects_end();
+ //hobject_t enumerate_objects_begin(int n, int m);
+ void enumerate_objects(
+ int64_t pool_id,
+ const std::string &ns,
+ const hobject_t &start,
+ const hobject_t &end,
+ const uint32_t max,
+ std::list<librados::ListObjectImpl> *result,
+ hobject_t *next,
+ Context *on_finish);
+
+ void _enumerate_reply(
+ bufferlist &bl,
+ int r,
+ const hobject_t &end,
+ const int64_t pool_id,
+ int budget,
+ epoch_t reply_epoch,
+ std::list<librados::ListObjectImpl> *result,
+ hobject_t *next,
+ Context *on_finish);
+ friend class C_EnumerateReply;
+
// -------------------------
// pool ops
private: