This will allow handle_osd_map to not stop other work queues.
Signed-off-by: Samuel Just <sam.just@inktank.com>
hobject_t logoid = make_pg_log_oid(pgid);
hobject_t infooid = make_pg_biginfo_oid(pgid);
if (osdmap->get_pg_type(pgid) == pg_pool_t::TYPE_REP)
- pg = new ReplicatedPG(this, pool, pgid, logoid, infooid);
+ pg = new ReplicatedPG(this, osdmap, pool, pgid, logoid, infooid);
else
assert(0);
return *_dout << pg->gen_prefix();
}
-/*
- * take osd->map_lock to get a valid osdmap reference
- */
void PG::lock(bool no_lockdep)
{
- osd->map_lock.get_read();
- OSDMapRef map = osd->osdmap;
- osd->map_lock.put_read();
_lock.Lock(no_lockdep);
- osdmap_ref.swap(map);
-
// if we have unrecorded dirty state with the lock dropped, there is a bug
assert(!dirty_info);
assert(!dirty_log);
dout(30) << "lock" << dendl;
}
-/*
- * caller holds osd->map_lock, no need to take it to get a valid
- * osdmap reference.
- */
void PG::lock_with_map_lock_held(bool no_lockdep)
{
_lock.Lock(no_lockdep);
- osdmap_ref = osd->osdmap;
-
// if we have unrecorded dirty state with the lock dropped, there is a bug
assert(!dirty_info);
assert(!dirty_log);
dout(30) << "reassert_lock_with_map_lock_held" << dendl;
}
-void PG::unlock()
-{
- dout(30) << "unlock" << dendl;
- assert(!dirty_info);
- assert(!dirty_log);
- osdmap_ref.reset();
- _lock.Unlock();
-}
-
std::string PG::gen_prefix() const
{
stringstream out;
void PG::handle_peering_event(CephPeeringEvtRef evt, RecoveryCtx *rctx)
{
+ if (!require_same_or_newer_map(evt->get_epoch_sent())) {
+ peering_waiters.push_back(evt);
+ return;
+ }
if (old_peering_evt(evt))
return;
assert(!deleting);
RecoveryCtx *rctx)
{
dout(10) << "handle_advance_map " << newup << "/" << newacting << dendl;
+ osdmap_ref = osdmap;
AdvMap evt(osdmap, lastmap, newup, newacting);
recovery_state.handle_event(evt, rctx);
}
/*** PG ****/
protected:
OSD *osd;
+ OSDMapRef osdmap_ref;
PGPool *pool;
- OSDMapRef osdmap_ref;
OSDMapRef get_osdmap() const {
assert(is_locked());
assert(osdmap_ref);
bool deleting; // true while RemoveWQ should be chewing on us
void lock(bool no_lockdep = false);
- void unlock();
+ void unlock() {
+ //generic_dout(0) << this << " " << info.pgid << " unlock" << dendl;
+ _lock.Unlock();
+ }
/* During handle_osd_map, the osd holds a write lock to the osdmap.
* *_with_map_lock_held assume that the map_lock is already held */
}
+ list<OpRequestRef> op_waiters;
list<OpRequestRef> op_queue; // op queue
bool dirty_info, dirty_log;
};
typedef std::tr1::shared_ptr<CephPeeringEvt> CephPeeringEvtRef;
list<CephPeeringEvtRef> peering_queue; // op queue
+ list<CephPeeringEvtRef> peering_waiters;
struct QueryState : boost::statechart::event< QueryState > {
Formatter *f;
public:
- PG(OSD *o, PGPool *_pool, pg_t p, const hobject_t& loid, const hobject_t& ioid) :
- osd(o), pool(_pool),
+ PG(OSD *o, OSDMapRef curmap,
+ PGPool *_pool, pg_t p, const hobject_t& loid, const hobject_t& ioid) :
+ osd(o), osdmap_ref(curmap), pool(_pool),
_lock("PG::_lock"),
ref(0), deleting(false), dirty_info(false), dirty_log(false),
info(p), coll(p), log_oid(loid), biginfo_oid(ioid),
bool old_peering_evt(CephPeeringEvtRef evt) {
return old_peering_msg(evt->get_epoch_sent(), evt->get_epoch_requested());
}
+ bool require_same_or_newer_map(epoch_t e) {
+ return e <= get_osdmap()->get_epoch();
+ }
// recovery bits
void take_waiters();
}
}
-ReplicatedPG::ReplicatedPG(OSD *o, PGPool *_pool, pg_t p, const hobject_t& oid, const hobject_t& ioid) :
- PG(o, _pool, p, oid, ioid), temp_created(false),
+ReplicatedPG::ReplicatedPG(OSD *o, OSDMapRef curmap,
+ PGPool *_pool, pg_t p, const hobject_t& oid,
+ const hobject_t& ioid) :
+ PG(o, curmap, _pool, p, oid, ioid), temp_created(false),
temp_coll(coll_t::make_temp_coll(p)), snap_trimmer_machine(this)
{
snap_trimmer_machine.initiate();
void ReplicatedPG::do_sub_op(OpRequestRef op)
{
MOSDSubOp *m = (MOSDSubOp*)op->request;
+ if (!require_same_or_newer_map(m->map_epoch)) {
+ op_waiters.push_back(op);
+ return;
+ }
assert(m->get_header().type == MSG_OSD_SUBOP);
dout(15) << "do_sub_op " << *op->request << dendl;
int get_pgls_filter(bufferlist::iterator& iter, PGLSFilter **pfilter);
public:
- ReplicatedPG(OSD *o, PGPool *_pool, pg_t p, const hobject_t& oid, const hobject_t& ioid);
+ ReplicatedPG(OSD *o, OSDMapRef curmap,
+ PGPool *_pool, pg_t p, const hobject_t& oid,
+ const hobject_t& ioid);
~ReplicatedPG() {}
int do_command(vector<string>& cmd, ostream& ss, bufferlist& idata, bufferlist& odata);