We have a request that is queued before a pool exists, there is one
epoch where it exists, and then the pool disappears again. The two maps
are processed at the same time. For the first we set needs_resend, map to
an osd, and remove from the homeless sessin. For the second, the pool
dne, we set osd back to -1, and send a map check request. Finally,
handle_osd_maps scans need_resend, sees the pool dne, and removes from
need_resend. The difference from the "usual" case is that we are neither
on the need_resend list nor on the homeless session.
Fix this by concluding immediately that the pool existed (briefly) and
then no longer exists.
Fixes: http://tracker.ceph.com/issues/19552
Signed-off-by: Sage Weil <sage@redhat.com>
{
// rwlock is locked unique
- if (op->attempts) {
- // we send a reply earlier, which means that previously the pool
- // existed, and now it does not (i.e., it was deleted).
+ if (op->target.pool_ever_existed) {
+ // the pool previously existed and now it does not, which means it
+ // was deleted.
op->map_dne_bound = osdmap->get_epoch();
ldout(cct, 10) << "check_op_pool_dne tid " << op->tid
<< " pool previously exists but now does not"
<< t->target_oloc << " -> pgid " << pgid << dendl;
ldout(cct,30) << __func__ << " target pi " << pi
<< " pg_num " << pi->get_pg_num() << dendl;
+ t->pool_ever_existed = true;
int size = pi->size;
int min_size = pi->min_size;
///< true if we are directed at base_pgid, not base_oid
bool precalc_pgid = false;
+ ///< true if we have ever mapped to a valid pool
+ bool pool_ever_existed = false;
+
///< explcit pg target, if any
pg_t base_pgid;