]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/filestore/HashIndex: fix list_by_hash_* termination on reaching end 12001/head
authorSage Weil <sage@redhat.com>
Thu, 10 Nov 2016 18:56:24 +0000 (13:56 -0500)
committerLoic Dachary <ldachary@redhat.com>
Tue, 15 Nov 2016 16:49:14 +0000 (17:49 +0100)
If we set *next to max, then the caller (a few lines up) doesn't terminate
the loop and will keep trying to list objects in every following hash
dir until it reaches the end of the collection.  In fact, if we have an
end bound we will never to an efficient listing unless we hit the max
first.

For one user, this was causing OSD suicides when scrub ran because it
wasn't able to list all objects before the timeout.  In general, this would
cause scrub to stall a PG for a long time and slow down requests.

Broken by refactor in 921c4586f165ce39c17ef8b579c548dc8f6f4500.

Fixes: http://tracker.ceph.com/issues/17859
Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit c5180262a086c2d3895aff4bf0fb0ff9a6666149)

src/os/filestore/HashIndex.cc

index 606e1f57d90b042c88ea23bc968c20edf312601d..1839a0488361379b2cf22b1e3336bc206f6a9fb3 100644 (file)
@@ -1065,7 +1065,7 @@ int HashIndex::list_by_hash_bitwise(
        }
        if (cmp_bitwise(j->second, end) >= 0) {
          if (next)
-           *next = ghobject_t::get_max();
+           *next = j->second;
          return 0;
        }
        if (!next || cmp_bitwise(j->second, *next) >= 0) {
@@ -1131,7 +1131,7 @@ int HashIndex::list_by_hash_nibblewise(
        }
        if (cmp_nibblewise(j->second, end) >= 0) {
          if (next)
-           *next = ghobject_t::get_max();
+           *next = j->second;
          return 0;
        }
        if (!next || cmp_nibblewise(j->second, *next) >= 0) {