]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: track snap collections per pg, and clean them up
authorSage Weil <sage@newdream.net>
Fri, 17 Oct 2008 20:27:11 +0000 (13:27 -0700)
committerSage Weil <sage@newdream.net>
Fri, 17 Oct 2008 20:27:11 +0000 (13:27 -0700)
Explicitly track which snap collections exist for each pg.  Clean them
up when the PG is destroyed.

src/include/buffer.h
src/osd/OSD.cc
src/osd/PG.cc
src/osd/PG.h
src/osd/ReplicatedPG.cc

index 65ddbd98310566a83b2fcc8624dbbc8f8185afa1..6170b095ed43fa3057173a5f8cb120a2dc3d1c78 100644 (file)
@@ -414,6 +414,8 @@ public:
       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);
index c0fee4622eea6ca0be0fdd324a8b54790a9e957e..88133b737a65dbcfe5a29dca91c7429104201033 100644 (file)
@@ -549,8 +549,7 @@ PG *OSD::_create_lock_pg(pg_t pgid, ObjectStore::Transaction& t)
   // 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;
 }
@@ -606,15 +605,30 @@ void OSD::_remove_unlock_pg(PG *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);
@@ -648,14 +662,8 @@ void OSD::load_pgs()
     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);
index 6aaec544dae4d53779f6df4304b96b662afe3a8a..a7446420f27a2b3c641bbbe61c81895310134c58 100644 (file)
@@ -1424,6 +1424,50 @@ void PG::read_log(ObjectStore *store)
 
 
 
+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
index ae970bd9fce5b3053742da5f26c28c1643a0be5e..83da068e2684b885ec64e497d08b4f8ddcc1806d 100644 (file)
@@ -513,6 +513,7 @@ public:
   IndexedLog  log;
   OndiskLog   ondisklog;
   Missing     missing;
+  set<snapid_t> snap_collections;
 
 protected:
   int         role;    // 0 = primary, 1 = replica, -1=none.
@@ -699,6 +700,11 @@ public:
   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) {
index e11a89e7dccf5083da271a9c7f07ecc6ba60e351..02e539a0d6751be590610bf898f8b8d082617adf 100644 (file)
@@ -423,14 +423,12 @@ bool ReplicatedPG::snap_trimmer()
     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);
@@ -829,12 +827,10 @@ void ReplicatedPG::prepare_transaction(ObjectStore::Transaction& t, osd_reqid_t
       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);
       }
 
@@ -1832,11 +1828,11 @@ void ReplicatedPG::sub_op_push(MOSDSubOp *op)
     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);
       }
     }
   }