]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
objecter: fix pgls
authorSage Weil <sage@inktank.com>
Fri, 1 Jun 2012 22:44:51 +0000 (15:44 -0700)
committerSage Weil <sage@inktank.com>
Fri, 1 Jun 2012 23:11:18 +0000 (16:11 -0700)
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 <sage@inktank.com>
Reviewed-by: Sam Just <sam.just@inktank.com>
src/osdc/Objecter.cc
src/osdc/Objecter.h

index c7b9e281030e159905b91ebfb832860611d89351..3be08f22c6d7d899e482ef6f041a5e044d240176 100644 (file)
@@ -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!
index d0c69ee67b6ed349ebeba1f52f13964115c3b2a2..61accb712fdc1a74a3a3591f3c3098aa9cbb695b 100644 (file)
@@ -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();