p != removed_snaps.m.end();
p++)
for (snapid_t t = 0; t < p->second; ++t)
- pg->info.removed_snaps.insert(p->first + t);
- dout(10) << *pg << " removed_snaps now " << pg->info.removed_snaps << dendl;
+ pg->info.dead_snaps.insert(p->first + t);
+ dout(10) << *pg << " dead_snaps now " << pg->info.dead_snaps << dendl;
bufferlist bl;
::encode(pg->info, bl);
t.collection_setattr(pg->info.pgid.to_coll(), "info", bl);
if (pg->is_active()) {
// update started counter
pg->info.history.last_epoch_started = osdmap->get_epoch();
- if (!pg->info.removed_snaps.empty())
+ if (!pg->info.dead_snaps.empty())
pg->queue_snap_trim();
}
else if (pg->is_primary() && !pg->is_active()) {
eversion_t log_bottom; // oldest log entry.
bool log_backlog; // do we store a complete log?
- set<snapid_t> removed_snaps; // snaps we need to trim
+ set<snapid_t> dead_snaps; // snaps we need to trim
struct History {
epoch_t epoch_created; // epoch in which PG was created
::encode(log_bottom, bl);
::encode(log_backlog, bl);
history.encode(bl);
- ::encode(removed_snaps, bl);
+ ::encode(dead_snaps, bl);
}
void decode(bufferlist::iterator &bl) {
::decode(pgid, bl);
::decode(log_bottom, bl);
::decode(log_backlog, bl);
history.decode(bl);
- ::decode(removed_snaps, bl);
+ ::decode(dead_snaps, bl);
}
};
WRITE_CLASS_ENCODER(Info::History)
//out << " (" << pg.log.bottom << "," << pg.log.top << "]";
if (pg.missing.num_missing()) out << " m=" << pg.missing.num_missing();
if (pg.missing.num_lost()) out << " l=" << pg.missing.num_lost();
- if (pg.info.removed_snaps.size())
- out << " rs=" << pg.info.removed_snaps;
+ if (pg.info.dead_snaps.size())
+ out << " dead=" << pg.info.dead_snaps;
out << "]";
bool ReplicatedPG::snap_trimmer()
{
lock();
- dout(10) << "snap_trimmer" << dendl;
+ dout(10) << "snap_trimmer start" << dendl;
state_clear(PG_STATE_SNAPTRIMQUEUE);
state_set(PG_STATE_SNAPTRIMMING);
update_stats();
- while (info.removed_snaps.size() &&
+ while (info.dead_snaps.size() &&
is_active()) {
- snapid_t sn = *info.removed_snaps.begin();
+ snapid_t sn = *info.dead_snaps.begin();
coll_t c = info.pgid.to_snap_coll(sn);
vector<pobject_t> ls;
osd->store->collection_list(c, ls);
for (vector<pobject_t>::iterator p = ls.begin(); p != ls.end(); p++) {
pobject_t coid = *p;
+ // load clone snap list
bufferlist bl;
osd->store->getattr(info.pgid.to_coll(), coid, "snaps", bl);
bufferlist::iterator blp = bl.begin();
vector<snapid_t> snaps;
::decode(snaps, blp);
+
+ // load head snapset
+ pobject_t head = coid;
+ head.oid.snap = CEPH_NOSNAP;
+ bl.clear();
+ osd->store->getattr(info.pgid.to_coll(), head, "snapset", bl);
+ blp = bl.begin();
+ SnapSet snapset;
+ ::decode(snapset, blp);
+ dout(10) << coid << " old head " << head << " snapset " << snapset << dendl;
+
+ // remove snaps
vector<snapid_t> newsnaps;
for (unsigned i=0; i<snaps.size(); i++)
if (!osd->osdmap->is_removed_snap(snaps[i]))
- newsnaps.push_back(i);
-
+ newsnaps.push_back(snaps[i]);
+ else {
+ vector<snapid_t>::iterator q = snapset.snaps.begin();
+ while (*q != snaps[i]) q++; // it should be in there
+ snapset.snaps.erase(q);
+ }
if (newsnaps.empty()) {
- // remove
+ // remove clone
dout(10) << coid << " snaps " << snaps << " -> " << newsnaps << " ... deleting" << dendl;
t.remove(info.pgid.to_coll(), coid);
t.collection_remove(info.pgid.to_snap_coll(snaps[0]), coid);
if (snaps.size() > 1)
t.collection_remove(info.pgid.to_snap_coll(snaps[snaps.size()-1]), coid);
- // adjust head snapset
- pobject_t head = coid;
- head.oid.snap = CEPH_NOSNAP;
- bufferlist bl;
- osd->store->getattr(info.pgid.to_coll(), head, "snapset", bl);
- bufferlist::iterator blp = bl.begin();
- SnapSet snapset;
- ::decode(snapset, blp);
- dout(10) << coid << " old head " << head << " snapset " << snapset << dendl;
-
+ // ...from snapset
snapid_t last = coid.oid.snap;
vector<snapid_t>::iterator p;
for (p = snapset.clones.begin(); p != snapset.clones.end(); p++)
}
snapset.clones.erase(p);
snapset.clone_overlap.erase(last);
-
- dout(10) << coid << " new head " << head << " snapset " << snapset << dendl;
-
- if (snapset.clones.empty() && !snapset.head_exists) {
- dout(10) << coid << " removing head " << head << dendl;
- t.remove(info.pgid.to_coll(), head);
- } else {
- bl.clear();
- ::encode(snapset, bl);
- t.setattr(info.pgid.to_coll(), head, "snapset", bl);
- }
} else {
// save adjusted snaps for this object
dout(10) << coid << " snaps " << snaps << " -> " << newsnaps << dendl;
t.collection_add(info.pgid.to_snap_coll(newsnaps[newsnaps.size()-1]), info.pgid.to_coll(), coid);
}
}
+
+ // save head snapset
+ dout(10) << coid << " new head " << head << " snapset " << snapset << dendl;
+ if (snapset.clones.empty() && !snapset.head_exists) {
+ dout(10) << coid << " removing head " << head << dendl;
+ t.remove(info.pgid.to_coll(), head);
+ } else {
+ bl.clear();
+ ::encode(snapset, bl);
+ t.setattr(info.pgid.to_coll(), head, "snapset", bl);
+ }
+
osd->store->apply_transaction(t);
// give other threads a chance at this pg
lock();
}
- info.removed_snaps.erase(sn);
+ info.dead_snaps.erase(sn);
}
// done