opv.back().op.op = CEPH_OSD_OP_WATCH;
opv.back().op.watch.cookie = info->linger_id;
opv.back().op.watch.op = CEPH_OSD_WATCH_OP_RECONNECT;
+ opv.back().op.watch.gen = ++info->register_gen;
oncommit = new C_Linger_Reconnect(this, info);
} else {
ldout(cct, 15) << "send_linger " << info->linger_id << " register" << dendl;
opv[0].op.op = CEPH_OSD_OP_WATCH;
opv[0].op.watch.cookie = info->linger_id;
opv[0].op.watch.op = CEPH_OSD_WATCH_OP_PING;
+ opv[0].op.watch.gen = info->register_gen;
C_Linger_Ping *onack = new C_Linger_Ping(this, info);
Op *o = new Op(info->target.base_oid, info->target.base_oloc,
opv, info->target.flags | CEPH_OSD_FLAG_READ,
logger->inc(l_osdc_linger_ping);
}
-void Objecter::_linger_ping(LingerOp *info, int r, utime_t sent)
+void Objecter::_linger_ping(LingerOp *info, int r, utime_t sent,
+ uint32_t register_gen)
{
ldout(cct, 10) << __func__ << " " << info->linger_id
- << " sent " << sent << " = " << r
- << " (last_error " << info->last_error << ")" << dendl;
+ << " sent " << sent << " gen " << register_gen << " = " << r
+ << " (last_error " << info->last_error
+ << " register_gen " << info->register_gen << ")" << dendl;
info->watch_lock.Lock();
- if (r == 0) {
- info->watch_valid_thru = sent;
- } else if (r < 0) {
- info->last_error = r;
- if (info->watch_context)
- finisher->queue(new C_DoWatchError(info, r));
+ if (info->register_gen == register_gen) {
+ if (r == 0) {
+ info->watch_valid_thru = sent;
+ } else if (r < 0) {
+ info->last_error = r;
+ if (info->watch_context)
+ finisher->queue(new C_DoWatchError(info, r));
+ }
+ info->watch_cond.SignalAll();
+ } else {
+ ldout(cct, 20) << " ignoring old gen" << dendl;
}
- info->watch_cond.SignalAll();
info->watch_lock.Unlock();
}
Mutex watch_lock;
Cond watch_cond;
+ uint32_t register_gen;
bool registered;
bool canceled;
Context *on_reg_ack, *on_reg_commit;
is_watch(false),
last_error(0),
watch_lock("Objecter::LingerOp::watch_lock"),
+ register_gen(0),
registered(false),
canceled(false),
on_reg_ack(NULL), on_reg_commit(NULL),
Objecter *objecter;
LingerOp *info;
utime_t sent;
- C_Linger_Ping(Objecter *o, LingerOp *l) : objecter(o), info(l) {
+ uint32_t register_gen;
+ C_Linger_Ping(Objecter *o, LingerOp *l)
+ : objecter(o), info(l), register_gen(info->register_gen) {
info->get();
}
~C_Linger_Ping() {
info->put();
}
void finish(int r) {
- objecter->_linger_ping(info, r, sent);
+ objecter->_linger_ping(info, r, sent, register_gen);
}
};
void _linger_commit(LingerOp *info, int r);
void _linger_reconnect(LingerOp *info, int r);
void _send_linger_ping(LingerOp *info);
- void _linger_ping(LingerOp *info, int r, utime_t sent);
+ void _linger_ping(LingerOp *info, int r, utime_t sent, uint32_t register_gen);
void _check_op_pool_dne(Op *op, bool session_locked);
void _send_op_map_check(Op *op);