// Populate Op::target
OSDSession *s = NULL;
- _calc_target(&info->target);
+ _calc_target(&info->target, &info->last_force_resend);
// Create LingerOp<->OSDSession relation
int r = _get_session(info->target.osd, &s, lc);
Op *op = p->second;
++p; // check_op_pool_dne() may touch ops; prevent iterator invalidation
ldout(cct, 10) << " checking op " << op->tid << dendl;
- int r = _calc_target(&op->target);
+ int r = _calc_target(&op->target, &op->last_force_resend);
switch (r) {
case RECALC_OP_TARGET_NO_ACTION:
if (!force_resend &&
p != need_resend_linger.end(); ++p) {
LingerOp *op = *p;
if (!op->session) {
- _calc_target(&op->target);
+ _calc_target(&op->target, &op->last_force_resend);
OSDSession *s = NULL;
int const r = _get_session(op->target.osd, &s, lc);
assert(r == 0);
assert(op->session == NULL);
OSDSession *s = NULL;
- bool const check_for_latest_map = _calc_target(&op->target) == RECALC_OP_TARGET_POOL_DNE;
+ bool const check_for_latest_map = _calc_target(&op->target, &op->last_force_resend) == RECALC_OP_TARGET_POOL_DNE;
// Try to get a session, including a retry if we need to take write lock
int r = _get_session(op->target.osd, &s, lc);
return p->raw_hash_to_pg(p->hash_key(key, ns));
}
-int Objecter::_calc_target(op_target_t *t, bool any_change)
+int Objecter::_calc_target(op_target_t *t, epoch_t *last_force_resend, bool any_change)
{
assert(rwlock.is_locked());
bool force_resend = false;
bool need_check_tiering = false;
if (osdmap->get_epoch() == pi->last_force_op_resend) {
- force_resend = true;
+ if (last_force_resend && *last_force_resend < pi->last_force_op_resend) {
+ *last_force_resend = pi->last_force_op_resend;
+ force_resend = true;
+ } else if (last_force_resend == 0)
+ force_resend = true;
}
if (t->target_oid.name.empty() || force_resend) {
t->target_oid = t->base_oid;
{
assert(rwlock.is_wlocked());
- int r = _calc_target(&linger_op->target, true);
+ int r = _calc_target(&linger_op->target, &linger_op->last_force_resend, true);
if (r == RECALC_OP_TARGET_NEED_RESEND) {
ldout(cct, 10) << "recalc_linger_op_target tid " << linger_op->linger_id
<< " pgid " << linger_op->target.pgid
int *data_offset;
+ epoch_t last_force_resend;
+
Op(const object_t& o, const object_locator_t& ol, vector<OSDOp>& op,
int f, Context *ac, Context *co, version_t *ov, int *offset = NULL) :
session(NULL), incarnation(0),
budgeted(false),
should_resend(true),
ctx_budgeted(false),
- data_offset(offset) {
+ data_offset(offset),
+ last_force_resend(0) {
ops.swap(op);
/* initialize out_* to match op vector */
ceph_tid_t ping_tid;
epoch_t map_dne_bound;
+ epoch_t last_force_resend;
+
void _queued_async() {
assert(watch_lock.is_locked());
watch_pending_async.push_back(ceph_clock_now(NULL));
session(NULL),
register_tid(0),
ping_tid(0),
- map_dne_bound(0) {}
+ map_dne_bound(0),
+ last_force_resend(0) {}
// no copy!
const LingerOp &operator=(const LingerOp& r);
bool _osdmap_full_flag() const;
bool target_should_be_paused(op_target_t *op);
- int _calc_target(op_target_t *t, bool any_change=false);
+ int _calc_target(op_target_t *t, epoch_t *last_force_resend=0, bool any_change=false);
int _map_session(op_target_t *op, OSDSession **s,
RWLock::Context& lc);