unsigned p_off; // in *p
public:
// constructor. position.
+ iterator() :
+ bl(0), ls(0), off(0), p_off(0) {}
iterator(list *l, unsigned o=0) :
bl(l), ls(&bl->_buffers), off(0), p(ls->begin()), p_off(0) {
advance(o);
// create collection
assert(!store->collection_exists(pgid.to_coll()));
t.create_collection(pgid.to_coll());
-
- pg->write_log(t);
+ pg->write_state(t);
return pg;
}
// remove from store
vector<pobject_t> olist;
- store->collection_list(pgid.to_coll(), olist);
-
+
ObjectStore::Transaction t;
{
+ // snap collections
+ for (set<snapid_t>::iterator p = pg->snap_collections.begin();
+ p != pg->snap_collections.end();
+ p++) {
+ vector<pobject_t> olist;
+ store->collection_list(pgid.to_snap_coll(*p), olist);
+ for (vector<pobject_t>::iterator p = olist.begin();
+ p != olist.end();
+ p++)
+ t.remove(pgid.to_coll(), *p);
+ }
+
+ // log
+ t.remove(pgid.to_coll(), pgid.to_pobject());
+
+ // main collection
+ store->collection_list(pgid.to_coll(), olist);
for (vector<pobject_t>::iterator p = olist.begin();
p != olist.end();
p++)
t.remove(pgid.to_coll(), *p);
- t.remove(pgid.to_coll(), pgid.to_pobject()); // log too
t.remove_collection(pgid.to_coll());
}
store->apply_transaction(t);
pg_t pgid = it->high;
PG *pg = _open_lock_pg(pgid);
- // read pg info
- bufferlist bl;
- store->collection_getattr(pgid.to_coll(), "info", bl);
- bufferlist::iterator p = bl.begin();
- ::decode(pg->info, p);
-
- // read pg log
- pg->read_log(store);
+ // read pg state, log
+ pg->read_state(store);
// generate state for current mapping
int nrep = osdmap->pg_to_acting_osds(pgid, pg->acting);
+void PG::read_state(ObjectStore *store)
+{
+ bufferlist bl;
+ bufferlist::iterator p;
+
+ // info
+ store->collection_getattr(info.pgid.to_coll(), "info", bl);
+ p = bl.begin();
+ ::decode(info, p);
+
+ // snap_collections
+ bl.clear();
+ store->collection_getattr(info.pgid.to_coll(), "snap_collections", bl);
+ p = bl.begin();
+ ::decode(snap_collections, p);
+
+ read_log(store);
+}
+
+void PG::write_state(ObjectStore::Transaction& t)
+{
+ bufferlist bl;
+ ::encode(snap_collections, bl);
+ t.collection_setattr(info.pgid.to_coll(), "snap_collections", bl);
+
+ write_log(t); // will write_info().
+}
+
+coll_t PG::make_snap_collection(ObjectStore::Transaction& t, snapid_t s)
+{
+ coll_t c = info.pgid.to_snap_coll(s);
+ if (snap_collections.count(s) == 0) {
+ snap_collections.insert(s);
+ dout(10) << "create_snap_collection " << c << ", set now " << snap_collections << dendl;
+ bufferlist bl;
+ ::encode(snap_collections, bl);
+ t.collection_setattr(info.pgid.to_coll(), "snap_collections", bl);
+ t.create_collection(c);
+ }
+ return c;
+}
+
+
+
// ==============================
// Object locking
IndexedLog log;
OndiskLog ondisklog;
Missing missing;
+ set<snapid_t> snap_collections;
protected:
int role; // 0 = primary, 1 = replica, -1=none.
void read_log(ObjectStore *store);
void trim_ondisklog_to(ObjectStore::Transaction& t, eversion_t v);
+ void read_state(ObjectStore *store);
+ coll_t make_snap_collection(ObjectStore::Transaction& t, snapid_t sn);
+
+ void write_state(ObjectStore::Transaction &t);
+
void queue_snap_trim();
bool is_dup(osd_reqid_t rid) {
osd->store->collection_list(c, ls);
dout(10) << "snap_trimmer collection " << c << " has " << ls.size() << " items" << dendl;
- if (ls.empty())
- continue;
-
- ObjectStore::Transaction t;
for (vector<pobject_t>::iterator p = ls.begin(); p != ls.end(); p++) {
pobject_t coid = *p;
+ ObjectStore::Transaction t;
+
// load clone snap list
bufferlist bl;
osd->store->getattr(info.pgid.to_coll(), coid, "snaps", bl);
t.setattr(info.pgid.to_coll(), coid, "version", &at_version, sizeof(at_version));
// add to snap bound collections
- coll_t fc = info.pgid.to_snap_coll(snaps[0]);
- t.create_collection(fc);
+ coll_t fc = make_snap_collection(t, snaps[0]);
t.collection_add(fc, info.pgid.to_coll(), coid);
if (snaps.size() > 1) {
- coll_t lc = info.pgid.to_snap_coll(snaps[snaps.size()-1]);
- t.create_collection(lc);
+ coll_t lc = make_snap_collection(t, snaps[snaps.size()-1]);
t.collection_add(lc, info.pgid.to_coll(), coid);
}
bufferlist::iterator p = bl.begin();
::decode(snaps, p);
if (snaps.size()) {
- t.create_collection(info.pgid.to_snap_coll(snaps[0]));
- t.collection_add(info.pgid.to_snap_coll(snaps[0]), info.pgid.to_coll(), poid);
+ coll_t lc = make_snap_collection(t, snaps[0]);
+ t.collection_add(lc, info.pgid.to_coll(), poid);
if (snaps.size() > 1) {
- t.create_collection(info.pgid.to_snap_coll(snaps[snaps.size()-1]));
- t.collection_add(info.pgid.to_snap_coll(snaps[snaps.size()-1]), info.pgid.to_coll(), poid);
+ coll_t hc = make_snap_collection(t, snaps[snaps.size()-1]);
+ t.collection_add(hc, info.pgid.to_coll(), poid);
}
}
}