osd/PGBackend::be_scan_list: only call stat, getattrs once per object
We call back into be_scan_list repeatedly for the same object in deep
scrub if the object is too large/has too many omap entries to be done
in a single call. This causes us to wastefully call
ObjectStore::getattrs and stat multiple times.
This has been a long standing, but mostly harmless bug (aside from the
extra metadata traffic). However,
1a4d3f018, between reef and squid,
switched ScrubMap::object::attrs to a map<string, bufferlist> from a
map<string, bufferptr>. This should have been harmless, except that
the ObjectStore::getattrs overload for that type uses
aset[i->first].append(i->second);
rather than
aset.emplace(i.first.c_str(), i.second);
to populate the map. Combined with this bug, that means that if we
need 7 calls into be_scan_list to deep scrub an object, we'll end up
with attributes concatenated 7 times each. This didn't cause visible
problems with squid/main testing since all of the replicas would end
up doing the same thing and they'd still decode ok, but it did become
visible during reef->squid upgrade testing as the older osds sent
maps with the correct contents.
The next commit will fix ObjectStore::getattrs to clear the map.
Fixes: https://tracker.ceph.com/issues/65185
Signed-off-by: Samuel Just <sjust@redhat.com>
(cherry picked from commit
5671e8555eddc622a6edb926e67dadce79e6add5)