}
}
+void OSD::trim_maps(epoch_t oldest, int nreceived, bool skip_maps)
+{
+ epoch_t min = std::min(oldest, service.map_cache.cached_key_lower_bound());
+ if (superblock.oldest_map >= min)
+ return;
+
+ int num = 0;
+ ObjectStore::Transaction *t = NULL;
+ for (epoch_t e = superblock.oldest_map; e < min; ++e) {
+ dout(20) << " removing old osdmap epoch " << e << dendl;
+ if (!t) {
+ t = new ObjectStore::Transaction;
+ }
+ t->remove(META_COLL, get_osdmap_pobject_name(e));
+ t->remove(META_COLL, get_inc_osdmap_pobject_name(e));
+ superblock.oldest_map = e + 1;
+ num++;
+ if (num >= cct->_conf->osd_target_transaction_size && num >= nreceived) {
+ service.publish_superblock(superblock);
+ write_superblock(*t);
+ store->queue_transaction_and_cleanup(NULL, t);
+ t = NULL;
+ num = 0;
+ if (!skip_maps) {
+ // skip_maps leaves us with a range of old maps if we fail to remove all
+ // of them before moving superblock.oldest_map forward to the first map
+ // in the incoming MOSDMap msg. so we should continue removing them in
+ // this case, even we could do huge series of delete transactions all at
+ // once.
+ break;
+ }
+ }
+ }
+ if (num > 0) {
+ service.publish_superblock(superblock);
+ write_superblock(*t);
+ store->queue_transaction_and_cleanup(NULL, t);
+ }
+ // we should not remove the cached maps
+ assert(min <= service.map_cache.cached_key_lower_bound());
+}
+
void OSD::handle_osd_map(MOSDMap *m)
{
assert(osd_lock.is_locked());
}
if (superblock.oldest_map) {
- int num = 0;
- epoch_t min(
- MIN(m->oldest_map,
- service.map_cache.cached_key_lower_bound()));
- for (epoch_t e = superblock.oldest_map; e < min; ++e) {
- dout(20) << " removing old osdmap epoch " << e << dendl;
- t.remove(META_COLL, get_osdmap_pobject_name(e));
- t.remove(META_COLL, get_inc_osdmap_pobject_name(e));
- superblock.oldest_map = e+1;
- num++;
- if (num >= cct->_conf->osd_target_transaction_size &&
- (uint64_t)num > (last - first)) // make sure we at least keep pace with incoming maps
- break;
- }
+ // make sure we at least keep pace with incoming maps
+ trim_maps(m->oldest_map, last - first + 1, skip_maps);
}
if (!superblock.oldest_map || skip_maps)