From: Sage Weil Date: Fri, 1 Jun 2012 22:44:51 +0000 (-0700) Subject: objecter: fix pgls X-Git-Tag: v0.48argonaut~142 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d8e07a34e824d55252c29c22b5011934b6fe064a;p=ceph.git objecter: fix pgls First problem: if the osd returns more entries than we ask for, max_entries was going negative, and we were requesting (u64)(-small number) on the next iteration, slamming the OSD when the PG was big. We fix that by finishing response_size >= max_entries. Second problem: AFAICS we were not requesting the second chunk on a large PG at all, here, if the OSD returned less than what we wanted. Fix this by asking for more in that case. That means we detect the end of a PG in two ways: * if the OSD sets the return value to 1 (instead of 0) * if we get 0 items in the response Another patch will change the OSD behavior to return 1, and all will be well. If we run against an old OSD, we'll send an extra request for each PG and get nothing back before we realize we've hit the end and move on. Signed-off-by: Sage Weil Reviewed-by: Sam Just --- diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index c7b9e281030..3be08f22c6d 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -1385,7 +1385,8 @@ void Objecter::list_objects(ListContext *list_context, Context *onfinish) { op_submit(o); } -void Objecter::_list_reply(ListContext *list_context, bufferlist *bl, Context *final_finish, epoch_t reply_epoch) +void Objecter::_list_reply(ListContext *list_context, int r, bufferlist *bl, + Context *final_finish, epoch_t reply_epoch) { ldout(cct, 10) << "_list_reply" << dendl; @@ -1410,14 +1411,24 @@ void Objecter::_list_reply(ListContext *list_context, bufferlist *bl, Context *f if (response_size) { ldout(cct, 20) << "got a response with objects, proceeding" << dendl; list_context->list.merge(response.entries); - list_context->max_entries -= response_size; - ldout(cct, 20) << "cleaning up and exiting" << dendl; - if (!list_context->max_entries) { + if (response_size >= list_context->max_entries) { final_finish->finish(0); delete bl; delete final_finish; return; } + + // ask for fewer objects next time around + list_context->max_entries -= response_size; + + // if the osd returns 1 (newer code), or no entries, it means we + // hit the end of the pg. + if (r == 0 && response_size > 0) { + // not yet done with this pg + delete bl; + list_objects(list_context, final_finish); + return; + } } // if we make this this far, there are no objects left in the current pg, but we want more! diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index d0c69ee67b6..61accb712fd 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -713,7 +713,7 @@ public: list_context(lc), final_finish(finish), bl(b), objecter(ob), epoch(0) {} void finish(int r) { if (r >= 0) { - objecter->_list_reply(list_context, bl, final_finish, epoch); + objecter->_list_reply(list_context, r, bl, final_finish, epoch); } else { final_finish->finish(r); delete final_finish; @@ -881,7 +881,7 @@ public: void reopen_session(OSDSession *session); void close_session(OSDSession *session); - void _list_reply(ListContext *list_context, bufferlist *bl, Context *final_finish, + void _list_reply(ListContext *list_context, int r, bufferlist *bl, Context *final_finish, epoch_t reply_epoch); void resend_mon_ops();