}
// there can be no waiters here, so we don't call wake_pg_waiters
+ pg->ch = store->open_collection(pg->coll);
+
// read pg state, log
pg->read_state(store, bl);
PG* child = _make_pg(nextmap, *i);
child->lock(true);
out_pgs->insert(child);
+ rctx->created_pgs.insert(child);
unsigned split_bits = i->get_split_bits(pg_num);
dout(10) << "pg_num is " << pg_num << dendl;
return rctx;
}
+struct C_OpenPGs : public Context {
+ set<PGRef> pgs;
+ ObjectStore *store;
+ C_OpenPGs(set<PGRef>& p, ObjectStore *s) : store(s) {
+ pgs.swap(p);
+ }
+ void finish(int r) {
+ for (auto p : pgs) {
+ p->ch = store->open_collection(p->coll);
+ assert(p->ch);
+ }
+ }
+};
+
void OSD::dispatch_context_transaction(PG::RecoveryCtx &ctx, PG *pg,
ThreadPool::TPHandle *handle)
{
if (!ctx.transaction->empty()) {
+ if (!ctx.created_pgs.empty()) {
+ ctx.on_applied->add(new C_OpenPGs(ctx.created_pgs, store));
+ }
ctx.on_applied->add(new ObjectStore::C_DeleteTransaction(ctx.transaction));
int tr = store->queue_transaction(
pg->osr.get(),
delete ctx.info_map;
if ((ctx.on_applied->empty() &&
ctx.on_safe->empty() &&
- ctx.transaction->empty()) || !pg) {
+ ctx.transaction->empty() &&
+ ctx.created_pgs.empty()) || !pg) {
delete ctx.transaction;
delete ctx.on_applied;
delete ctx.on_safe;
+ assert(ctx.created_pgs.empty());
} else {
+ if (!ctx.created_pgs.empty()) {
+ ctx.on_applied->add(new C_OpenPGs(ctx.created_pgs, store));
+ }
ctx.on_applied->add(new ObjectStore::C_DeleteTransaction(ctx.transaction));
int tr = store->queue_transaction(
pg->osr.get(),
void upgrade(ObjectStore *store);
const coll_t coll;
+ ObjectStore::CollectionHandle ch;
PGLog pg_log;
static string get_info_key(spg_t pgid) {
return stringify(pgid) + "_info";
map<int, map<spg_t, pg_query_t> > *query_map;
map<int, vector<pair<pg_notify_t, pg_interval_map_t> > > *info_map;
map<int, vector<pair<pg_notify_t, pg_interval_map_t> > > *notify_list;
+ set<PGRef> created_pgs;
C_Contexts *on_applied;
C_Contexts *on_safe;
ObjectStore::Transaction *transaction;