]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/ObjectStore: combine Sequencer and CollectionImpl in ObjectStore
authorSage Weil <sage@redhat.com>
Mon, 15 Jan 2018 21:23:46 +0000 (15:23 -0600)
committerSage Weil <sage@redhat.com>
Tue, 6 Feb 2018 14:21:29 +0000 (08:21 -0600)
In practice we have a sequencer per collection. Combine them in the interface
to simplify our lives!

Signed-off-by: Sage Weil <sage@redhat.com>
33 files changed:
src/os/FuseStore.cc
src/os/ObjectStore.cc
src/os/ObjectStore.h
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/os/filestore/FileStore.cc
src/os/filestore/FileStore.h
src/os/kstore/KStore.cc
src/os/kstore/KStore.h
src/os/memstore/MemStore.cc
src/os/memstore/MemStore.h
src/osd/OSD.cc
src/osd/OSD.h
src/osd/PG.cc
src/osd/PG.h
src/osd/PrimaryLogPG.cc
src/osd/PrimaryLogPG.h
src/test/objectstore/DeterministicOpSequence.cc
src/test/objectstore/DeterministicOpSequence.h
src/test/objectstore/FileStoreDiff.cc
src/test/objectstore/FileStoreTracker.cc
src/test/objectstore/TestObjectStoreState.cc
src/test/objectstore/TestObjectStoreState.h
src/test/objectstore/store_test.cc
src/test/objectstore/store_test_fixture.h
src/test/objectstore/test_idempotent.cc
src/test/objectstore/test_idempotent_sequence.cc
src/test/objectstore/test_memstore_clone.cc
src/test/objectstore_bench.cc
src/test/osd/TestPGLog.cc
src/test/test_trans.cc
src/tools/ceph_objectstore_tool.cc
src/tools/ceph_objectstore_tool.h

index 21198c71c1f54f457d1b8424db98d440c22a79db..48aaa4407eeb18ad213610fea750c46409c1d2de 100644 (file)
@@ -715,6 +715,8 @@ static int os_mkdir(const char *path, mode_t mode)
 
   std::lock_guard<std::mutex> l(fs->lock);
 
+  ObjectStore::CollectionHandle ch;
+
   ObjectStore::Transaction t;
   switch (f) {
   case FN_OBJECT:
@@ -728,6 +730,7 @@ static int os_mkdir(const char *path, mode_t mode)
        }
       }
       t.touch(cid, oid);
+      ch = fs->store->open_collection(cid);
     }
     break;
 
@@ -742,6 +745,8 @@ static int os_mkdir(const char *path, mode_t mode)
       mode = 0;
     }
     t.create_collection(cid, mode);
+
+    ch = fs->store->open_collection(coll_t::meta());
     break;
 
   default:
@@ -749,11 +754,9 @@ static int os_mkdir(const char *path, mode_t mode)
   }
 
   if (!t.empty()) {
-    ceph::shared_ptr<ObjectStore::Sequencer> osr(
-      new ObjectStore::Sequencer("fuse"));
-    fs->store->apply_transaction(&*osr, std::move(t));
+    fs->store->apply_transaction(ch, std::move(t));
     C_SaferCond waiter;
-    if (!osr->flush_commit(&waiter))
+    if (!ch->flush_commit(&waiter))
       waiter.wait();
   }
 
@@ -784,6 +787,8 @@ static int os_create(const char *path, mode_t mode, struct fuse_file_info *fi)
 
   std::lock_guard<std::mutex> l(fs->lock);
 
+  ObjectStore::CollectionHandle ch = fs->store->open_collection(cid);
+
   ObjectStore::Transaction t;
   bufferlist *pbl = 0;
   switch (f) {
@@ -826,11 +831,9 @@ static int os_create(const char *path, mode_t mode, struct fuse_file_info *fi)
   }
 
   if (!t.empty()) {
-    ceph::shared_ptr<ObjectStore::Sequencer> osr(
-      new ObjectStore::Sequencer("fuse"));
-    fs->store->apply_transaction(&*osr, std::move(t));
+    fs->store->apply_transaction(ch, std::move(t));
     C_SaferCond waiter;
-    if (!osr->flush_commit(&waiter))
+    if (!ch->flush_commit(&waiter))
       waiter.wait();
   }
 
@@ -934,6 +937,8 @@ int os_flush(const char *path, struct fuse_file_info *fi)
   if (!o->dirty)
     return 0;
 
+  ObjectStore::CollectionHandle ch = fs->store->open_collection(cid);
+
   ObjectStore::Transaction t;
 
   switch (f) {
@@ -961,11 +966,9 @@ int os_flush(const char *path, struct fuse_file_info *fi)
     return 0;
   }
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr(
-    new ObjectStore::Sequencer("fuse"));
-  fs->store->apply_transaction(&*osr, std::move(t));
+  fs->store->apply_transaction(ch, std::move(t));
   C_SaferCond waiter;
-  if (!osr->flush_commit(&waiter))
+  if (!ch->flush_commit(&waiter))
     waiter.wait();
 
   return 0;
@@ -987,6 +990,7 @@ static int os_unlink(const char *path)
 
   std::lock_guard<std::mutex> l(fs->lock);
 
+  ObjectStore::CollectionHandle ch;
   ObjectStore::Transaction t;
 
   switch (f) {
@@ -996,10 +1000,12 @@ static int os_unlink(const char *path)
       keys.insert(key);
       t.omap_rmkeys(cid, oid, keys);
     }
+    ch = fs->store->open_collection(cid);
     break;
 
   case FN_OBJECT_ATTR_VAL:
     t.rmattr(cid, oid, key.c_str());
+    ch = fs->store->open_collection(cid);
     break;
 
   case FN_OBJECT_OMAP_HEADER:
@@ -1007,10 +1013,12 @@ static int os_unlink(const char *path)
       bufferlist empty;
       t.omap_setheader(cid, oid, empty);
     }
+    ch = fs->store->open_collection(cid);
     break;
 
   case FN_OBJECT:
     t.remove(cid, oid);
+    ch = fs->store->open_collection(cid);
     break;
 
   case FN_COLLECTION:
@@ -1023,21 +1031,21 @@ static int os_unlink(const char *path)
         return -ENOTEMPTY;
       t.remove_collection(cid);
     }
+    ch = fs->store->open_collection(coll_t::meta());
     break;
 
   case FN_OBJECT_DATA:
     t.truncate(cid, oid, 0);
+    ch = fs->store->open_collection(cid);
     break;
 
   default:
     return -EPERM;
   }
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr(
-    new ObjectStore::Sequencer("fuse"));
-  fs->store->apply_transaction(&*osr, std::move(t));
+  fs->store->apply_transaction(ch, std::move(t));
   C_SaferCond waiter;
-  if (!osr->flush_commit(&waiter))
+  if (!ch->flush_commit(&waiter))
     waiter.wait();
 
   return 0;
@@ -1078,13 +1086,12 @@ static int os_truncate(const char *path, off_t size)
     }
   }
 
+  ObjectStore::CollectionHandle ch = fs->store->open_collection(cid);
   ObjectStore::Transaction t;
   t.truncate(cid, oid, size);
-  ceph::shared_ptr<ObjectStore::Sequencer> osr(
-    new ObjectStore::Sequencer("fuse"));
-  fs->store->apply_transaction(&*osr, std::move(t));
+  fs->store->apply_transaction(ch, std::move(t));
   C_SaferCond waiter;
-  if (!osr->flush_commit(&waiter))
+  if (!ch->flush_commit(&waiter))
     waiter.wait();
   return 0;
 }
index 44bf75ffbebc1dc8e7fb06157d6504be35dc9983..12c9dca711380aaf8e40aaecb24e0a500bc747ae 100644 (file)
@@ -155,17 +155,12 @@ int ObjectStore::read_meta(const std::string& key,
 
 
 
-ostream& operator<<(ostream& out, const ObjectStore::Sequencer& s)
-{
-  return out << "osr(" << s.get_name() << " " << &s << ")";
-}
-
 ostream& operator<<(ostream& out, const ObjectStore::Transaction& tx) {
 
   return out << "Transaction(" << &tx << ")"; 
 }
 
-unsigned ObjectStore::apply_transactions(Sequencer *osr,
+unsigned ObjectStore::apply_transactions(CollectionHandle& ch,
                                         vector<Transaction>& tls,
                                         Context *ondisk)
 {
@@ -176,7 +171,7 @@ unsigned ObjectStore::apply_transactions(Sequencer *osr,
   bool done;
   C_SafeCond *onreadable = new C_SafeCond(&my_lock, &my_cond, &done, &r);
 
-  queue_transactions(osr, tls, onreadable, ondisk);
+  queue_transactions(ch, tls, onreadable, ondisk);
 
   my_lock.Lock();
   while (!done)
@@ -186,7 +181,7 @@ unsigned ObjectStore::apply_transactions(Sequencer *osr,
 }
 
 int ObjectStore::queue_transactions(
-  Sequencer *osr,
+  CollectionHandle& ch,
   vector<Transaction>& tls,
   Context *onreadable,
   Context *oncommit,
@@ -199,6 +194,6 @@ int ObjectStore::queue_transactions(
     onreadable, _complete);
   Context *_oncommit = new Wrapper<RunOnDeleteRef>(
     oncommit, _complete);
-  return queue_transactions(osr, tls, _onreadable, _oncommit,
+  return queue_transactions(ch, tls, _onreadable, _oncommit,
                            onreadable_sync, op);
 }
index 8456360307ae581dd508e87667142f0e08574069..e9f8713c2a979b1e5c188de66fd82ee89a25a6a9 100644 (file)
@@ -17,6 +17,7 @@
 #include "include/Context.h"
 #include "include/buffer.h"
 #include "include/types.h"
+#include "include/stringify.h"
 #include "osd/osd_types.h"
 #include "common/TrackedOp.h"
 #include "common/WorkQueue.h"
@@ -117,101 +118,46 @@ public:
   virtual const PerfCounters* get_perf_counters() const = 0;
 
   /**
-   * a sequencer orders transactions
+   * a collection also orders transactions
    *
-   * Any transactions queued under a given sequencer will be applied in
-   * sequence.  Transactions queued under different sequencers may run
+   * Any transactions queued under a given collection will be applied in
+   * sequence.  Transactions queued under different collections may run
    * in parallel.
    *
-   * Clients of ObjectStore create and maintain their own Sequencer objects.
-   * When a list of transactions is queued the caller specifies a Sequencer to be used.
-   *
+   * ObjectStore users my get collection handles with open_collection() (or,
+   * for bootstrapping a new collection, create_new_collection()).
    */
+  struct CollectionImpl : public RefCountedObject {
+    const coll_t cid;
 
-  /**
-   * ABC for Sequencer implementation, private to the ObjectStore derived class.
-   * created in ...::queue_transaction(s)
-   */
-  struct Sequencer_impl : public RefCountedObject {
-    CephContext* cct;
+    CollectionImpl(const coll_t& c)
+      : RefCountedObject(NULL, 0),
+       cid(c) {}
 
+    /// wait for any queued transactions to apply
     // block until any previous transactions are visible.  specifically,
     // collection_list and collection_empty need to reflect prior operations.
     virtual void flush() = 0;
 
-    // called when we are done with the impl.  the impl may have a different
-    // (longer) lifecycle than the Sequencer.
-    virtual void discard() {}
-
     /**
      * Async flush_commit
      *
      * There are two cases:
-     * 1) sequencer is currently idle: the method returns true.  c is
+     * 1) collection is currently idle: the method returns true.  c is
      *    not touched.
-     * 2) sequencer is not idle: the method returns false and c is
+     * 2) collection is not idle: the method returns false and c is
      *    called asyncronously with a value of 0 once all transactions
-     *    queued on this sequencer prior to the call have been applied
+     *    queued on this collection prior to the call have been applied
      *    and committed.
      */
-    virtual bool flush_commit(
-      Context *c ///< [in] context to call upon flush/commit
-      ) = 0; ///< @return true if idle, false otherwise
-
-    Sequencer_impl(CephContext* cct) : RefCountedObject(NULL, 0), cct(cct)  {}
-    ~Sequencer_impl() override {}
-  };
-  typedef boost::intrusive_ptr<Sequencer_impl> Sequencer_implRef;
-
-  /**
-   * External (opaque) sequencer implementation
-   */
-  struct Sequencer {
-    string name;
-    spg_t shard_hint;
-    Sequencer_implRef p;
-
-    explicit Sequencer(string n)
-      : name(n), shard_hint(spg_t()), p(NULL) {
-    }
-    ~Sequencer() {
-      if (p)
-       p->discard();  // tell impl we are done with it
-    }
-
-    /// return a unique string identifier for this sequencer
-    const string& get_name() const {
-      return name;
-    }
-    /// wait for any queued transactions on this sequencer to apply
-    void flush() {
-      if (p)
-       p->flush();
-    }
+    virtual bool flush_commit(Context *c) = 0;
 
-    /// @see Sequencer_impl::flush_commit()
-    bool flush_commit(Context *c) {
-      if (!p) {
-       return true;
-      } else {
-       return p->flush_commit(c);
-      }
+    const coll_t &get_cid() {
+      return cid;
     }
   };
-
-  struct CollectionImpl : public RefCountedObject {
-    virtual const coll_t &get_cid() = 0;
-    CollectionImpl() : RefCountedObject(NULL, 0) {}
-  };
   typedef boost::intrusive_ptr<CollectionImpl> CollectionHandle;
 
-  struct CompatCollectionHandle : public CollectionImpl {
-    coll_t cid;
-    explicit CompatCollectionHandle(coll_t c) : cid(c) {}
-    const coll_t &get_cid() override {
-      return cid;
-    }
-  };
 
   /*********************************
    *
@@ -1484,24 +1430,24 @@ public:
   };
 
   // synchronous wrappers
-  unsigned apply_transaction(Sequencer *osr, Transaction&& t, Context *ondisk=0) {
+  unsigned apply_transaction(CollectionHandle& ch, Transaction&& t, Context *ondisk=0) {
     vector<Transaction> tls;
     tls.push_back(std::move(t));
-    return apply_transactions(osr, tls, ondisk);
+    return apply_transactions(ch, tls, ondisk);
   }
-  unsigned apply_transactions(Sequencer *osr, vector<Transaction>& tls, Context *ondisk=0);
+  unsigned apply_transactions(CollectionHandle& ch, vector<Transaction>& tls, Context *ondisk=0);
 
-  int queue_transaction(Sequencer *osr, Transaction&& t, Context *onreadable, Context *ondisk=0,
+  int queue_transaction(CollectionHandle& ch, Transaction&& t, Context *onreadable, Context *ondisk=0,
                                Context *onreadable_sync=0,
                                TrackedOpRef op = TrackedOpRef(),
                                ThreadPool::TPHandle *handle = NULL) {
     vector<Transaction> tls;
     tls.push_back(std::move(t));
-    return queue_transactions(osr, tls, onreadable, ondisk, onreadable_sync,
+    return queue_transactions(ch, tls, onreadable, ondisk, onreadable_sync,
                              op, handle);
   }
 
-  int queue_transactions(Sequencer *osr, vector<Transaction>& tls,
+  int queue_transactions(CollectionHandle& ch, vector<Transaction>& tls,
                         Context *onreadable, Context *ondisk=0,
                         Context *onreadable_sync=0,
                         TrackedOpRef op = TrackedOpRef(),
@@ -1510,17 +1456,17 @@ public:
     tls.back().register_on_applied(onreadable);
     tls.back().register_on_commit(ondisk);
     tls.back().register_on_applied_sync(onreadable_sync);
-    return queue_transactions(osr, tls, op, handle);
+    return queue_transactions(ch, tls, op, handle);
   }
 
   virtual int queue_transactions(
-    Sequencer *osr, vector<Transaction>& tls,
+    CollectionHandle& ch, vector<Transaction>& tls,
     TrackedOpRef op = TrackedOpRef(),
     ThreadPool::TPHandle *handle = NULL) = 0;
 
 
   int queue_transactions(
-    Sequencer *osr,
+    CollectionHandle& ch,
     vector<Transaction>& tls,
     Context *onreadable,
     Context *oncommit,
@@ -1529,7 +1475,7 @@ public:
     TrackedOpRef op);
 
   int queue_transaction(
-    Sequencer *osr,
+    CollectionHandle& ch,
     Transaction&& t,
     Context *onreadable,
     Context *oncommit,
@@ -1540,7 +1486,7 @@ public:
     vector<Transaction> tls;
     tls.push_back(std::move(t));
     return queue_transactions(
-      osr, tls, onreadable, oncommit, onreadable_sync, oncomplete, op);
+      ch, tls, onreadable, oncommit, onreadable_sync, oncomplete, op);
   }
 
  public:
@@ -1686,9 +1632,16 @@ public:
    * Provide a trivial handle as a default to avoid converting legacy
    * implementations.
    */
-  virtual CollectionHandle open_collection(const coll_t &cid) {
-    return new CompatCollectionHandle(cid);
-  }
+  virtual CollectionHandle open_collection(const coll_t &cid) = 0;
+
+  /**
+   * get a collection handle for a soon-to-be-created collection
+   *
+   * This handle must be used by queue_transaction that includes a
+   * create_collection call in order to become valid.  It will become the
+   * reference to the created collection.
+   */
+  virtual CollectionHandle create_new_collection(const coll_t &cid) = 0;
 
 
   /**
@@ -2086,14 +2039,6 @@ public:
 WRITE_CLASS_ENCODER(ObjectStore::Transaction)
 WRITE_CLASS_ENCODER(ObjectStore::Transaction::TransactionData)
 
-static inline void intrusive_ptr_add_ref(ObjectStore::Sequencer_impl *s) {
-  s->get();
-}
-static inline void intrusive_ptr_release(ObjectStore::Sequencer_impl *s) {
-  s->put();
-}
-
-ostream& operator<<(ostream& out, const ObjectStore::Sequencer& s);
 ostream& operator<<(ostream& out, const ObjectStore::Transaction& tx);
 
 #endif
index 00aeaeba87ce4fcd7354208c88580ea96e7c8506..d2f5206082821cec42a534b5babf834fe900d21c 100644 (file)
@@ -3216,13 +3216,25 @@ void BlueStore::DeferredBatch::_audit(CephContext *cct)
 #define dout_prefix *_dout << "bluestore(" << store->path << ").collection(" << cid << " " << this << ") "
 
 BlueStore::Collection::Collection(BlueStore *ns, Cache *c, coll_t cid)
-  : store(ns),
+  : CollectionImpl(cid),
+    store(ns),
+    osr(new OpSequencer(store)),
     cache(c),
-    cid(cid),
     lock("BlueStore::Collection::lock", true, false),
     exists(true),
     onode_map(c)
 {
+  osr->shard = cid.hash_to_shard(ns->m_finisher_num);
+}
+
+bool BlueStore::Collection::flush_commit(Context *c)
+{
+  return osr->flush_commit(c);
+}
+
+void BlueStore::Collection::flush()
+{
+  osr->flush();
 }
 
 void BlueStore::Collection::open_shared_blob(uint64_t sbid, BlobRef b)
@@ -5633,7 +5645,6 @@ int BlueStore::umount()
   dout(1) << __func__ << dendl;
 
   _osr_drain_all();
-  _osr_unregister_all();
 
   mounted = false;
   if (!_kv_only) {
@@ -6493,6 +6504,18 @@ ObjectStore::CollectionHandle BlueStore::open_collection(const coll_t& cid)
   return _get_collection(cid);
 }
 
+ObjectStore::CollectionHandle BlueStore::create_new_collection(
+  const coll_t& cid)
+{
+  RWLock::WLocker l(coll_lock);
+  Collection *c = new Collection(
+    this,
+    cache_shards[cid.hash_to_shard(cache_shards.size())],
+    cid);
+  new_coll_map[cid] = c;
+  return c;
+}
+
 bool BlueStore::exists(const coll_t& cid, const ghobject_t& oid)
 {
   CollectionHandle c = _get_collection(cid);
@@ -7996,9 +8019,10 @@ void BlueStore::get_db_statistics(Formatter *f)
   db->get_statistics(f);
 }
 
-BlueStore::TransContext *BlueStore::_txc_create(OpSequencer *osr)
+BlueStore::TransContext *BlueStore::_txc_create(
+  Collection *c, OpSequencer *osr)
 {
-  TransContext *txc = new TransContext(cct, osr);
+  TransContext *txc = new TransContext(cct, c, osr);
   txc->t = db->get_transaction();
   osr->queue_new(txc);
   dout(20) << __func__ << " osr " << osr << " = " << txc
@@ -8418,8 +8442,14 @@ void BlueStore::_txc_finish(TransContext *txc)
   }
 
   if (empty && osr->zombie) {
-    dout(10) << __func__ << " reaping empty zombie osr " << osr << dendl;
-    osr->_unregister();
+    std::lock_guard<std::mutex> l(zombie_osr_lock);
+    auto p = zombie_osr_set.find(osr);
+    if (p != zombie_osr_set.end()) {
+      dout(10) << __func__ << " reaping empty zombie osr " << osr << dendl;
+      zombie_osr_set.erase(p);
+    } else {
+      dout(10) << __func__ << " empty zombie osr " << osr << " already reaped" << dendl;
+    }
   }
 }
 
@@ -8434,6 +8464,14 @@ void BlueStore::_txc_release_alloc(TransContext *txc)
   txc->released.clear();
 }
 
+void BlueStore::_osr_register_zombie(OpSequencer *osr)
+{
+  std::lock_guard<std::mutex> l(zombie_osr_lock);
+  dout(10) << __func__ << " " << osr << dendl;
+  osr->zombie = true;
+  zombie_osr_set.insert(osr);
+}
+
 void BlueStore::_osr_drain_preceding(TransContext *txc)
 {
   OpSequencer *osr = txc->osr.get();
@@ -8463,9 +8501,19 @@ void BlueStore::_osr_drain_all()
   dout(10) << __func__ << dendl;
 
   set<OpSequencerRef> s;
+  set<OpSequencerRef> zombies;
   {
-    std::lock_guard<std::mutex> l(osr_lock);
-    s = osr_set;
+    RWLock::RLocker l(coll_lock);
+    for (auto& i : coll_map) {
+      s.insert(i.second->osr);
+    }
+  }
+  {
+    std::lock_guard<std::mutex> l(zombie_osr_lock);
+    for (auto& i : zombie_osr_set) {
+      s.insert(i);
+      zombies.insert(i);
+    }
   }
   dout(20) << __func__ << " osr_set " << s << dendl;
 
@@ -8489,35 +8537,24 @@ void BlueStore::_osr_drain_all()
   }
   --deferred_aggressive;
 
-  dout(10) << __func__ << " done" << dendl;
-}
-
-void BlueStore::_osr_unregister_all()
-{
-  set<OpSequencerRef> s;
   {
-    std::lock_guard<std::mutex> l(osr_lock);
-    s = osr_set;
-  }
-  dout(10) << __func__ << " " << s << dendl;
-  for (auto osr : s) {
-    osr->_unregister();
-
-    if (!osr->zombie) {
-      // break link from Sequencer to us so that this OpSequencer
-      // instance can die with this mount/umount cycle.  note that
-      // we assume umount() will not race against ~Sequencer.
-      assert(osr->parent);
-      osr->parent->p.reset();
+    std::lock_guard<std::mutex> l(zombie_osr_lock);
+    for (auto& osr : zombies) {
+      auto p = zombie_osr_set.find(osr);
+      if (p != zombie_osr_set.end()) {
+       dout(10) << __func__ << " reaping empty zombie osr " << osr << dendl;
+       zombie_osr_set.erase(p);
+      } else {
+       dout(10) << __func__ << " empty zombie osr " << osr << " already reaped" << dendl;
+      }
+      assert(osr->q.empty());
     }
   }
-  // nobody should be creating sequencers during umount either.
-  {
-    std::lock_guard<std::mutex> l(osr_lock);
-    assert(osr_set.empty());
-  }
+
+  dout(10) << __func__ << " done" << dendl;
 }
 
+
 void BlueStore::_kv_start()
 {
   dout(10) << __func__ << dendl;
@@ -9073,9 +9110,16 @@ void BlueStore::_deferred_aio_finish(OpSequencer *osr)
 int BlueStore::_deferred_replay()
 {
   dout(10) << __func__ << " start" << dendl;
-  OpSequencerRef osr = new OpSequencer(cct, this);
   int count = 0;
   int r = 0;
+  CollectionRef ch = _get_collection(coll_t::meta());
+  bool fake_ch = false;
+  if (!ch) {
+    // hmm, replaying initial mkfs?
+    ch = static_cast<Collection*>(create_new_collection(coll_t::meta()).get());
+    fake_ch = true;
+  }
+  OpSequencer *osr = static_cast<OpSequencer*>(ch->osr.get());
   KeyValueDB::Iterator it = db->get_iterator(PREFIX_DEFERRED);
   for (it->lower_bound(string()); it->valid(); it->next(), ++count) {
     dout(20) << __func__ << " replay " << pretty_binary_string(it->key())
@@ -9093,15 +9137,18 @@ int BlueStore::_deferred_replay()
       r = -EIO;
       goto out;
     }
-    TransContext *txc = _txc_create(osr.get());
+    TransContext *txc = _txc_create(ch.get(), osr);
     txc->deferred_txn = deferred_txn;
     txc->state = TransContext::STATE_KV_DONE;
     _txc_state_proc(txc);
   }
  out:
   dout(20) << __func__ << " draining osr" << dendl;
+  _osr_register_zombie(osr);
   _osr_drain_all();
-  osr->discard();
+  if (fake_ch) {
+    new_coll_map.clear();
+  }
   dout(10) << __func__ << " completed " << count << " events" << dendl;
   return r;
 }
@@ -9110,10 +9157,10 @@ int BlueStore::_deferred_replay()
 // transactions
 
 int BlueStore::queue_transactions(
-    Sequencer *posr,
-    vector<Transaction>& tls,
-    TrackedOpRef op,
-    ThreadPool::TPHandle *handle)
+  CollectionHandle& ch,
+  vector<Transaction>& tls,
+  TrackedOpRef op,
+  ThreadPool::TPHandle *handle)
 {
   FUNCTRACE(cct);
   list<Context *> on_applied, on_commit, on_applied_sync;
@@ -9131,22 +9178,13 @@ int BlueStore::queue_transactions(
     return 0;
   }
   utime_t start = ceph_clock_now();
-  // set up the sequencer
-  OpSequencer *osr;
-  assert(posr);
-  if (posr->p) {
-    osr = static_cast<OpSequencer *>(posr->p.get());
-    dout(10) << __func__ << " existing " << osr << " " << *osr << dendl;
-  } else {
-    osr = new OpSequencer(cct, this);
-    osr->parent = posr;
-    osr->shard = posr->shard_hint.hash_to_shard(m_finisher_num);
-    posr->p = osr;
-    dout(10) << __func__ << " new " << osr << " " << *osr << dendl;
-  }
+
+  Collection *c = static_cast<Collection*>(ch.get());
+  OpSequencer *osr = c->osr.get();
+  dout(10) << __func__ << " ch " << c << " " << c->cid << dendl;
 
   // prepare
-  TransContext *txc = _txc_create(osr);
+  TransContext *txc = _txc_create(static_cast<Collection*>(ch.get()), osr);
   txc->oncommits.swap(on_commit);
 
   for (vector<Transaction>::iterator p = tls.begin(); p != tls.end(); ++p) {
@@ -11465,13 +11503,12 @@ int BlueStore::_create_collection(
       r = -EEXIST;
       goto out;
     }
-    c->reset(
-      new Collection(
-       this,
-       cache_shards[cid.hash_to_shard(cache_shards.size())],
-       cid));
+    auto p = new_coll_map.find(cid);
+    assert(p != new_coll_map.end());
+    *c = p->second;
     (*c)->cnode.bits = bits;
     coll_map[cid] = *c;
+    new_coll_map.erase(p);
   }
   encode((*c)->cnode, bl);
   txc->t->set(PREFIX_COLL, stringify(cid), bl);
@@ -11533,6 +11570,7 @@ int BlueStore::_remove_collection(TransContext *txc, const coll_t &cid,
         coll_map.erase(cid);
         txc->removed_collections.push_back(*c);
         (*c)->exists = false;
+       _osr_register_zombie((*c)->osr.get());
         c->reset();
         txc->t->rmkey(PREFIX_COLL, stringify(cid));
         r = 0;
index 32f4cde3d9cd34f9f224f270e79a2fe42f723cd7..0d35849c58d28b32a0bf70c5cdea87ed2b84ffde 100644 (file)
@@ -1337,10 +1337,13 @@ public:
     bool map_any(std::function<bool(OnodeRef)> f);
   };
 
+  class OpSequencer;
+  typedef boost::intrusive_ptr<OpSequencer> OpSequencerRef;
+
   struct Collection : public CollectionImpl {
     BlueStore *store;
+    OpSequencerRef osr;
     Cache *cache;       ///< our cache shard
-    coll_t cid;
     bluestore_cnode_t cnode;
     RWLock lock;
 
@@ -1379,10 +1382,6 @@ public:
       return b;
     }
 
-    const coll_t &get_cid() override {
-      return cid;
-    }
-
     bool contains(const ghobject_t& oid) {
       if (cid.is_meta())
        return oid.hobj.pool == -1;
@@ -1396,6 +1395,9 @@ public:
 
     void split_cache(Collection *dest);
 
+    bool flush_commit(Context *c) override;
+    void flush() override;
+
     Collection(BlueStore *ns, Cache *ca, coll_t c);
   };
 
@@ -1418,9 +1420,6 @@ public:
     }
   };
 
-  class OpSequencer;
-  typedef boost::intrusive_ptr<OpSequencer> OpSequencerRef;
-
   struct volatile_statfs{
     enum {
       STATFS_ALLOCATED = 0,
@@ -1547,7 +1546,8 @@ public:
       last_stamp = now;
     }
 
-    OpSequencerRef osr;
+    CollectionRef ch;
+    OpSequencerRef osr;  // this should be ch->osr
     boost::intrusive::list_member_hook<> sequencer_item;
 
     uint64_t bytes = 0, cost = 0;
@@ -1577,8 +1577,9 @@ public:
     uint64_t last_nid = 0;     ///< if non-zero, highest new nid we allocated
     uint64_t last_blobid = 0;  ///< if non-zero, highest new blobid we allocated
 
-    explicit TransContext(CephContext* cct, OpSequencer *o)
-      : osr(o),
+    explicit TransContext(CephContext* cct, Collection *c, OpSequencer *o)
+      : ch(c),
+       osr(o),
        ioc(cct, this),
        start(ceph_clock_now()) {
       last_stamp = start;
@@ -1647,7 +1648,7 @@ public:
     }
   };
 
-  class OpSequencer : public Sequencer_impl {
+  class OpSequencer : public RefCountedObject {
   public:
     std::mutex qlock;
     std::condition_variable qcond;
@@ -1664,7 +1665,6 @@ public:
     DeferredBatch *deferred_running = nullptr;
     DeferredBatch *deferred_pending = nullptr;
 
-    Sequencer *parent;
     BlueStore *store;
 
     size_t shard;
@@ -1677,41 +1677,14 @@ public:
 
     std::atomic_int kv_submitted_waiters = {0};
 
-    std::atomic_bool registered = {true}; ///< registered in BlueStore's osr_set
-    std::atomic_bool zombie = {false};    ///< owning Sequencer has gone away
+    std::atomic_bool zombie = {false};    ///< in zombie_osr set (collection going away)
 
-    OpSequencer(CephContext* cct, BlueStore *store)
-      : Sequencer_impl(cct),
-       parent(NULL), store(store) {
-      store->register_osr(this);
+    OpSequencer(BlueStore *store)
+      : RefCountedObject(store->cct, 0),
+       store(store) {
     }
-    ~OpSequencer() override {
+    ~OpSequencer() {
       assert(q.empty());
-      _unregister();
-    }
-
-    void discard() override {
-      // Note that we may have txc's in flight when the parent Sequencer
-      // goes away.  Reflect this with zombie==registered==true and let
-      // _osr_drain_all clean up later.
-      assert(!zombie);
-      zombie = true;
-      parent = nullptr;
-      bool empty;
-      {
-       std::lock_guard<std::mutex> l(qlock);
-       empty = q.empty();
-      }
-      if (empty) {
-       _unregister();
-      }
-    }
-
-    void _unregister() {
-      if (registered) {
-       store->unregister_osr(this);
-       registered = false;
-      }
     }
 
     void queue_new(TransContext *txc) {
@@ -1742,7 +1715,7 @@ public:
       return false;
     }
 
-    void flush() override {
+    void flush() {
       std::unique_lock<std::mutex> l(qlock);
       while (true) {
        // set flag before the check because the condition
@@ -1758,7 +1731,7 @@ public:
       }
     }
 
-    bool flush_commit(Context *c) override {
+    bool flush_commit(Context *c) {
       std::lock_guard<std::mutex> l(qlock);
       if (q.empty()) {
        return true;
@@ -1839,11 +1812,12 @@ private:
 
   RWLock coll_lock = {"BlueStore::coll_lock"};  ///< rwlock to protect coll_map
   mempool::bluestore_cache_other::unordered_map<coll_t, CollectionRef> coll_map;
+  map<coll_t,CollectionRef> new_coll_map;
 
   vector<Cache*> cache_shards;
 
-  std::mutex osr_lock;              ///< protect osd_set
-  std::set<OpSequencerRef> osr_set; ///< set of all OpSequencers
+  std::mutex zombie_osr_lock;              ///< protect zombie_osr_set
+  std::set<OpSequencerRef> zombie_osr_set; ///< set of OpSequencers for deleted collections
 
   std::atomic<uint64_t> nid_last = {0};
   std::atomic<uint64_t> nid_max = {0};
@@ -2026,7 +2000,7 @@ private:
   void _dump_extent_map(ExtentMap& em, int log_level=30);
   void _dump_transaction(Transaction *t, int log_level = 30);
 
-  TransContext *_txc_create(OpSequencer *osr);
+  TransContext *_txc_create(Collection *c, OpSequencer *osr);
   void _txc_update_store_statfs(TransContext *txc);
   void _txc_add_transaction(TransContext *txc, Transaction *t);
   void _txc_calc_cost(TransContext *txc);
@@ -2045,9 +2019,9 @@ private:
   void _txc_finish(TransContext *txc);
   void _txc_release_alloc(TransContext *txc);
 
+  void _osr_register_zombie(OpSequencer *osr);
   void _osr_drain_preceding(TransContext *txc);
   void _osr_drain_all();
-  void _osr_unregister_all();
 
   void _kv_start();
   void _kv_stop();
@@ -2205,15 +2179,6 @@ public:
     f->close_section();
   }
 
-  void register_osr(OpSequencer *osr) {
-    std::lock_guard<std::mutex> l(osr_lock);
-    osr_set.insert(osr);
-  }
-  void unregister_osr(OpSequencer *osr) {
-    std::lock_guard<std::mutex> l(osr_lock);
-    osr_set.erase(osr);
-  }
-
 public:
   int statfs(struct store_statfs_t *buf) override;
 
@@ -2283,6 +2248,7 @@ public:
   int list_collections(vector<coll_t>& ls) override;
 
   CollectionHandle open_collection(const coll_t &c) override;
+  CollectionHandle create_new_collection(const coll_t& cid) override;
 
   bool collection_exists(const coll_t& c) override;
   int collection_empty(const coll_t& c, bool *empty) override;
@@ -2409,7 +2375,7 @@ public:
   }
 
   int queue_transactions(
-    Sequencer *osr,
+    CollectionHandle& ch,
     vector<Transaction>& tls,
     TrackedOpRef op = TrackedOpRef(),
     ThreadPool::TPHandle *handle = NULL) override;
@@ -2712,10 +2678,6 @@ private:
                        unsigned bits, int rem);
 };
 
-inline ostream& operator<<(ostream& out, const BlueStore::OpSequencer& s) {
-  return out << *s.parent;
-}
-
 static inline void intrusive_ptr_add_ref(BlueStore::Onode *o) {
   o->get();
 }
index 0a7f1bf8e0151922089437d969359a422c1d757a..c1a59f3a07f8b88f6762fbe777d97cbd2fa84a06 100644 (file)
@@ -156,7 +156,7 @@ void FileStore::FSPerfTracker::update_from_perfcounters(
 
 ostream& operator<<(ostream& out, const FileStore::OpSequencer& s)
 {
-  return out << *s.parent;
+  return out << "osr(" << s.cid << ")";
 }
 
 int FileStore::get_cdir(const coll_t& cid, char *s, int len)
@@ -535,6 +535,7 @@ FileStore::FileStore(CephContext* cct, const std::string &base,
   sync_entry_timeo_lock("FileStore::sync_entry_timeo_lock"),
   timer(cct, sync_entry_timeo_lock),
   stop(false), sync_thread(this),
+  coll_lock("FileStore::coll_lock"),
   fdcache(cct),
   wbthrottle(cct),
   next_osr_id(0),
@@ -1929,6 +1930,7 @@ void FileStore::init_temp_collections()
   for (vector<coll_t>::iterator p = ls.begin(); p != ls.end(); ++p) {
     if (p->is_temp())
       continue;
+    coll_map[*p] = new OpSequencer(cct, ++next_osr_id, *p);
     if (p->is_meta())
       continue;
     coll_t temp = p->get_temp();
@@ -2011,6 +2013,25 @@ int FileStore::umount()
 }
 
 
+/// -----------------------------
+
+ObjectStore::CollectionHandle FileStore::open_collection(const coll_t& c)
+{
+  Mutex::Locker l(coll_lock);
+  auto p = coll_map.find(c);
+  if (p == coll_map.end()) {
+    return CollectionHandle();
+  }
+  return p->second;
+}
+
+ObjectStore::CollectionHandle FileStore::create_new_collection(const coll_t& c)
+{
+  Mutex::Locker l(coll_lock);
+  auto *r = new OpSequencer(cct, ++next_osr_id, c);
+  coll_map[c] = r;
+  return r;
+}
 
 
 /// -----------------------------
@@ -2096,7 +2117,7 @@ void FileStore::_do_op(OpSequencer *osr, ThreadPool::TPHandle &handle)
   Op *o = osr->peek_queue();
   o->trace.event("op_apply_start");
   apply_manager.op_apply_start(o->op);
-  dout(5) << __FUNC__ << ": " << o << " seq " << o->op << " " << *osr << "/" << osr->parent << " start" << dendl;
+  dout(5) << __FUNC__ << ": " << o << " seq " << o->op << " " << *osr << " start" << dendl;
   o->trace.event("_do_transactions start");
   int r = _do_transactions(o->tls, o->op, &handle);
   o->trace.event("op_apply_finish");
@@ -2116,7 +2137,7 @@ void FileStore::_finish_op(OpSequencer *osr)
   utime_t lat = ceph_clock_now();
   lat -= o->start;
 
-  dout(10) << __FUNC__ << ": " << o << " seq " << o->op << " " << *osr << "/" << osr->parent << " lat " << lat << dendl;
+  dout(10) << __FUNC__ << ": " << o << " seq " << o->op << " " << *osr << " lat " << lat << dendl;
   osr->apply_lock.Unlock();  // locked in _do_op
   o->trace.event("_finish_op");
 
@@ -2152,7 +2173,7 @@ struct C_JournaledAhead : public Context {
   }
 };
 
-int FileStore::queue_transactions(Sequencer *posr, vector<Transaction>& tls,
+int FileStore::queue_transactions(CollectionHandle& ch, vector<Transaction>& tls,
                                  TrackedOpRef osd_op,
                                  ThreadPool::TPHandle *handle)
 {
@@ -2175,19 +2196,9 @@ int FileStore::queue_transactions(Sequencer *posr, vector<Transaction>& tls,
   }
 
   utime_t start = ceph_clock_now();
-  // set up the sequencer
-  OpSequencer *osr;
-  assert(posr);
-  if (posr->p) {
-    osr = static_cast<OpSequencer *>(posr->p.get());
-    dout(5) << __FUNC__ << ": existing " << osr << " " << *osr << dendl;
-  } else {
-    osr = new OpSequencer(cct, ++next_osr_id);
-    osr->set_cct(cct);
-    osr->parent = posr;
-    posr->p = osr;
-    dout(5) << __FUNC__ << ": new " << osr << " " << *osr << dendl;
-  }
+
+  OpSequencer *osr = static_cast<OpSequencer*>(ch.get());
+  dout(5) << __FUNC__ << ": osr " << osr << " " << *osr << dendl;
 
   // used to include osr information in tracepoints during transaction apply
   for (vector<Transaction>::iterator i = tls.begin(); i != tls.end(); ++i) {
@@ -2645,7 +2656,8 @@ void FileStore::_do_transaction(
   dout(10) << __FUNC__ << ": on " << &t << dendl;
 
 #ifdef WITH_LTTNG
-  const char *osr_name = t.get_osr() ? static_cast<OpSequencer*>(t.get_osr())->get_name().c_str() : "<NULL>";
+  string osr_name_str = stringify(static_cast<OpSequencer*>(t.get_osr())->cid);
+  const char *osr_name = osr_name_str.c_str();
 #endif
 
   Transaction::iterator i = t.begin();
@@ -5311,6 +5323,11 @@ int FileStore::_destroy_collection(const coll_t& c)
     goto out;
   }
 
+  {
+    Mutex::Locker l(coll_lock);
+    coll_map.erase(c);
+  }
+
  out:
   // destroy parallel temp collection, too
   if (!c.is_meta() && !c.is_temp()) {
@@ -5907,7 +5924,7 @@ void FileStore::dump_transactions(vector<ObjectStore::Transaction>& ls, uint64_t
   unsigned trans_num = 0;
   for (vector<ObjectStore::Transaction>::iterator i = ls.begin(); i != ls.end(); ++i, ++trans_num) {
     m_filestore_dump_fmt.open_object_section("transaction");
-    m_filestore_dump_fmt.dump_string("osr", osr->get_name());
+    m_filestore_dump_fmt.dump_stream("osr") << osr->cid;
     m_filestore_dump_fmt.dump_unsigned("seq", seq);
     m_filestore_dump_fmt.dump_unsigned("trans_num", trans_num);
     (*i).dump(&m_filestore_dump_fmt);
index d5711df039ea58e1629ce61932b1d301109667ab..87b9e2faa3d55828eabee6e2eb16a279cfa72cbd 100644 (file)
@@ -222,14 +222,14 @@ private:
     TrackedOpRef osd_op;
     ZTracer::Trace trace;
   };
-  class OpSequencer : public Sequencer_impl {
+  class OpSequencer : public CollectionImpl {
+    CephContext *cct;
     Mutex qlock; // to protect q, for benefit of flush (peek/dequeue also protected by lock)
     list<Op*> q;
     list<uint64_t> jq;
     list<pair<uint64_t, Context*> > flush_commit_waiters;
     Cond cond;
   public:
-    Sequencer *parent;
     Mutex apply_lock;  // for apply mutual exclusion
     int id;
 
@@ -347,20 +347,20 @@ private:
       }
     }
 
-    OpSequencer(CephContext* cct, int i)
-      : Sequencer_impl(cct),
+    OpSequencer(CephContext* cct, int i, coll_t cid)
+      : CollectionImpl(cid),
+       cct(cct),
        qlock("FileStore::OpSequencer::qlock", false, false),
-       parent(0),
        apply_lock("FileStore::OpSequencer::apply_lock", false, false),
         id(i) {}
     ~OpSequencer() override {
       assert(q.empty());
     }
-
-    const string& get_name() const {
-      return parent->get_name();
-    }
   };
+  typedef boost::intrusive_ptr<OpSequencer> OpSequencerRef;
+
+  Mutex coll_lock;
+  map<coll_t,OpSequencerRef> coll_map;
 
   friend ostream& operator<<(ostream& out, const OpSequencer& s);
 
@@ -519,7 +519,10 @@ public:
     Transaction& t, uint64_t op_seq, int trans_num,
     ThreadPool::TPHandle *handle);
 
-  int queue_transactions(Sequencer *osr, vector<Transaction>& tls,
+  CollectionHandle open_collection(const coll_t& c) override;
+  CollectionHandle create_new_collection(const coll_t& c) override;
+
+  int queue_transactions(CollectionHandle& ch, vector<Transaction>& tls,
                         TrackedOpRef op = TrackedOpRef(),
                         ThreadPool::TPHandle *handle = nullptr) override;
 
index 4ece4e7ee81310681a258ea490530b6d0c1f43fc..9cbe592416bb545e401d6a68be3e5f6d9e1450e9 100644 (file)
@@ -560,14 +560,26 @@ int KStore::OnodeHashLRU::trim(int max)
 #undef dout_prefix
 #define dout_prefix *_dout << "kstore(" << store->path << ").collection(" << cid << ") "
 
-KStore::Collection::Collection(KStore *ns, coll_t c)
-  : store(ns),
-    cid(c),
+KStore::Collection::Collection(KStore *ns, coll_t cid)
+  : CollectionImpl(cid),
+    store(ns),
     lock("KStore::Collection::lock", true, false),
+    osr(new OpSequencer()),
     onode_map(store->cct)
 {
 }
 
+void KStore::Collection::flush()
+{
+  osr->flush();
+}
+
+bool KStore::Collection::flush_commit(Context *c)
+{
+  return osr->flush_commit(c);
+}
+
+
 KStore::OnodeRef KStore::Collection::get_onode(
   const ghobject_t& oid,
   bool create)
@@ -1071,6 +1083,20 @@ int KStore::statfs(struct store_statfs_t* buf)
   return db->get_statfs(buf);
 }
 
+
+ObjectStore::CollectionHandle KStore::open_collection(const coll_t& cid)
+{
+  return _get_collection(cid);
+}
+
+ObjectStore::CollectionHandle KStore::create_new_collection(const coll_t& cid)
+{
+  auto *c = new Collection(this, cid);
+  RWLock::WLocker l(coll_lock);
+  new_coll_map[cid] = c;
+  return c;
+}
+
 // ---------------
 // cache
 
@@ -2133,10 +2159,10 @@ void KStore::_kv_sync_thread()
 // transactions
 
 int KStore::queue_transactions(
-    Sequencer *posr,
-    vector<Transaction>& tls,
-    TrackedOpRef op,
-    ThreadPool::TPHandle *handle)
+  CollectionHandle& ch,
+  vector<Transaction>& tls,
+  TrackedOpRef op,
+  ThreadPool::TPHandle *handle)
 {
   Context *onreadable;
   Context *ondisk;
@@ -2145,17 +2171,9 @@ int KStore::queue_transactions(
     tls, &onreadable, &ondisk, &onreadable_sync);
 
   // set up the sequencer
-  OpSequencer *osr;
-  assert(posr);
-  if (posr->p) {
-    osr = static_cast<OpSequencer *>(posr->p.get());
-    dout(10) << __func__ << " existing " << osr << " " << *osr << dendl;
-  } else {
-    osr = new OpSequencer(cct);
-    osr->parent = posr;
-    posr->p = osr;
-    dout(10) << __func__ << " new " << osr << " " << *osr << dendl;
-  }
+  Collection *c = static_cast<Collection*>(ch.get());
+  OpSequencer *osr = c->osr.get();
+  dout(10) << __func__ << " ch " << ch.get() << " " << c->cid << dendl;
 
   // prepare
   TransContext *txc = _txc_create(osr);
@@ -3275,9 +3293,13 @@ int KStore::_create_collection(
       r = -EEXIST;
       goto out;
     }
-    c->reset(new Collection(this, cid));
+    auto p = new_coll_map.find(cid);
+    assert(p != new_coll_map.end());
+    *c = p->second;
+    assert((*c)->cid == cid);
     (*c)->cnode.bits = bits;
     coll_map[cid] = *c;
+    new_coll_map.erase(p);
   }
   encode((*c)->cnode, bl);
   txc->t->set(PREFIX_COLL, stringify(cid), bl);
index 47534a7ff4ecd994f3504cd3a14e73ada22a1a18..c1a2a9c16e75a020ed0a8d3ee909fb8f55a08dbc 100644 (file)
@@ -130,22 +130,22 @@ public:
     int trim(int max=-1);
   };
 
+  class OpSequencer;
+  typedef boost::intrusive_ptr<OpSequencer> OpSequencerRef;
+
   struct Collection : public CollectionImpl {
     KStore *store;
-    coll_t cid;
     kstore_cnode_t cnode;
     RWLock lock;
 
+    OpSequencerRef osr;
+
     // cache onodes on a per-collection basis to avoid lock
     // contention.
     OnodeHashLRU onode_map;
 
     OnodeRef get_onode(const ghobject_t& oid, bool create);
 
-    const coll_t &get_cid() override {
-      return cid;
-    }
-
     bool contains(const ghobject_t& oid) {
       if (cid.is_meta())
        return oid.hobj.pool == -1;
@@ -157,6 +157,9 @@ public:
       return false;
     }
 
+    void flush() override;
+    bool flush_commit(Context *c) override;
+
     Collection(KStore *ns, coll_t c);
   };
   typedef boost::intrusive_ptr<Collection> CollectionRef;
@@ -180,9 +183,6 @@ public:
     }
   };
 
-  class OpSequencer;
-  typedef boost::intrusive_ptr<OpSequencer> OpSequencerRef;
-
   struct TransContext {
     typedef enum {
       STATE_PREPARE,
@@ -218,6 +218,7 @@ public:
         start = now;
     }
 
+    CollectionRef ch;
     OpSequencerRef osr;
     boost::intrusive::list_member_hook<> sequencer_item;
 
@@ -253,7 +254,7 @@ public:
     }
   };
 
-  class OpSequencer : public Sequencer_impl {
+  class OpSequencer : public RefCountedObject {
   public:
     std::mutex qlock;
     std::condition_variable qcond;
@@ -265,14 +266,7 @@ public:
        &TransContext::sequencer_item> > q_list_t;
     q_list_t q;  ///< transactions
 
-    Sequencer *parent;
-
-    OpSequencer(CephContext* cct)
-       //set the qlock to PTHREAD_MUTEX_RECURSIVE mode
-      : Sequencer_impl(cct),
-       parent(NULL) {
-    }
-    ~OpSequencer() override {
+    ~OpSequencer() {
       assert(q.empty());
     }
 
@@ -281,13 +275,13 @@ public:
       q.push_back(*txc);
     }
 
-    void flush() override {
+    void flush() {
       std::unique_lock<std::mutex> l(qlock);
       while (!q.empty())
        qcond.wait(l);
     }
 
-    bool flush_commit(Context *c) override {
+    bool flush_commit(Context *c) {
       std::lock_guard<std::mutex> l(qlock);
       if (q.empty()) {
        return true;
@@ -322,6 +316,7 @@ private:
 
   RWLock coll_lock;    ///< rwlock to protect coll_map
   ceph::unordered_map<coll_t, CollectionRef> coll_map;
+  map<coll_t,CollectionRef> new_coll_map;
 
   std::mutex nid_lock;
   uint64_t nid_last;
@@ -443,6 +438,9 @@ public:
 
   int statfs(struct store_statfs_t *buf) override;
 
+  CollectionHandle open_collection(const coll_t& c) override;
+  CollectionHandle create_new_collection(const coll_t& c) override;
+
   using ObjectStore::exists;
   bool exists(const coll_t& cid, const ghobject_t& oid) override;
   using ObjectStore::stat;
@@ -559,7 +557,7 @@ public:
 
 
   int queue_transactions(
-    Sequencer *osr,
+    CollectionHandle& ch,
     vector<Transaction>& tls,
     TrackedOpRef op = TrackedOpRef(),
     ThreadPool::TPHandle *handle = NULL) override;
@@ -669,10 +667,6 @@ private:
 
 };
 
-inline ostream& operator<<(ostream& out, const KStore::OpSequencer& s) {
-  return out << *s.parent;
-}
-
 static inline void intrusive_ptr_add_ref(KStore::Onode *o) {
   o->get();
 }
index 591788c16a218ac0d5eadba624cd101d36463116..a8197d19463deb02adf937da61ed87e7959c82f5 100644 (file)
@@ -247,6 +247,14 @@ MemStore::CollectionRef MemStore::get_collection(const coll_t& cid)
   return cp->second;
 }
 
+ObjectStore::CollectionHandle MemStore::create_new_collection(const coll_t& cid)
+{
+  RWLock::WLocker l(coll_lock);
+  Collection *c = new Collection(cct, cid);
+  new_coll_map[cid] = c;
+  return c;
+}
+
 
 // ---------------
 // read operations
@@ -684,30 +692,18 @@ ObjectMap::ObjectMapIterator MemStore::get_omap_iterator(const coll_t& cid,
 // ---------------
 // write operations
 
-int MemStore::queue_transactions(Sequencer *osr,
-                                vector<Transaction>& tls,
-                                TrackedOpRef op,
-                                ThreadPool::TPHandle *handle)
+int MemStore::queue_transactions(
+  CollectionHandle& ch,
+  vector<Transaction>& tls,
+  TrackedOpRef op,
+  ThreadPool::TPHandle *handle)
 {
   // because memstore operations are synchronous, we can implement the
   // Sequencer with a mutex. this guarantees ordering on a given sequencer,
   // while allowing operations on different sequencers to happen in parallel
-  struct OpSequencer : public Sequencer_impl {
-    OpSequencer(CephContext* cct) :
-      Sequencer_impl(cct) {}
-    std::mutex mutex;
-    void flush() override {}
-    bool flush_commit(Context*) override { return true; }
-  };
-
+  Collection *c = static_cast<Collection*>(ch.get());
   std::unique_lock<std::mutex> lock;
-  if (osr) {
-    if (!osr->p) {
-      osr->p = new OpSequencer(cct);
-    }
-    auto seq = static_cast<OpSequencer*>(osr->p.get());
-    lock = std::unique_lock<std::mutex>(seq->mutex);
-  }
+  lock = std::unique_lock<std::mutex>(c->sequencer_mutex);
 
   for (vector<Transaction>::iterator p = tls.begin(); p != tls.end(); ++p) {
     // poke the TPHandle heartbeat just to exercise that code path
@@ -1368,8 +1364,11 @@ int MemStore::_create_collection(const coll_t& cid, int bits)
   auto result = coll_map.insert(std::make_pair(cid, CollectionRef()));
   if (!result.second)
     return -EEXIST;
-  result.first->second.reset(new Collection(cct, cid));
+  auto p = new_coll_map.find(cid);
+  assert(p != new_coll_map.end());
+  result.first->second = p->second;
   result.first->second->bits = bits;
+  new_coll_map.erase(p);
   return 0;
 }
 
index ee5309e8e0299d5ea7bfe07a1ab26731752c301d..b8663122a0e0c9ee58788c7de9b0d06fe7992872 100644 (file)
@@ -96,7 +96,6 @@ public:
 
   struct PageSetObject;
   struct Collection : public CollectionImpl {
-    coll_t cid;
     int bits = 0;
     CephContext *cct;
     bool use_page_set;
@@ -105,15 +104,12 @@ public:
     map<string,bufferptr> xattr;
     RWLock lock;   ///< for object_{map,hash}
     bool exists;
+    std::mutex sequencer_mutex;
 
     typedef boost::intrusive_ptr<Collection> Ref;
     friend void intrusive_ptr_add_ref(Collection *c) { c->get(); }
     friend void intrusive_ptr_release(Collection *c) { c->put(); }
 
-    const coll_t &get_cid() override {
-      return cid;
-    }
-
     ObjectRef create_object() const;
 
     // NOTE: The lock only needs to protect the object_map/hash, not the
@@ -179,8 +175,14 @@ public:
       return result;
     }
 
+    void flush() override {
+    }
+    bool flush_commit(Context *c) override {
+      return true;
+    }
+
     explicit Collection(CephContext *cct, coll_t c)
-      : cid(c),
+      : CollectionImpl(c),
        cct(cct),
        use_page_set(cct->_conf->memstore_page_set),
         lock("MemStore::Collection::lock", true, false),
@@ -194,6 +196,7 @@ private:
 
   ceph::unordered_map<coll_t, CollectionRef> coll_map;
   RWLock coll_lock;    ///< rwlock to protect coll_map
+  map<coll_t,CollectionRef> new_coll_map;
 
   CollectionRef get_collection(const coll_t& cid);
 
@@ -313,8 +316,10 @@ public:
     bufferlist& bl,
     uint32_t op_flags = 0) override;
   using ObjectStore::fiemap;
-  int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override;
-  int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, map<uint64_t, uint64_t>& destmap) override;
+  int fiemap(const coll_t& cid, const ghobject_t& oid,
+            uint64_t offset, size_t len, bufferlist& bl) override;
+  int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset,
+            size_t len, map<uint64_t, uint64_t>& destmap) override;
   int getattr(const coll_t& cid, const ghobject_t& oid, const char *name,
              bufferptr& value) override;
   int getattr(CollectionHandle &c, const ghobject_t& oid, const char *name,
@@ -329,6 +334,7 @@ public:
   CollectionHandle open_collection(const coll_t& c) override {
     return get_collection(c);
   }
+  CollectionHandle create_new_collection(const coll_t& c) override;
   bool collection_exists(const coll_t& c) override;
   int collection_empty(const coll_t& c, bool *empty) override;
   int collection_bits(const coll_t& c) override;
@@ -401,7 +407,8 @@ public:
 
 
   int queue_transactions(
-    Sequencer *osr, vector<Transaction>& tls,
+    CollectionHandle& ch,
+    vector<Transaction>& tls,
     TrackedOpRef op = TrackedOpRef(),
     ThreadPool::TPHandle *handle = NULL) override;
 };
index 78f9a65841253e78c1eaaed0074fc701245c85e0..13809be1167cde5dbd42b63e5c6ad0d8019931c6 100644 (file)
@@ -204,7 +204,6 @@ CompatSet OSD::get_osd_compat_set() {
 OSDService::OSDService(OSD *osd) :
   osd(osd),
   cct(osd->cct),
-  meta_osr(new ObjectStore::Sequencer("meta")),
   whoami(osd->whoami), store(osd->store),
   log_client(osd->log_client), clog(osd->clog),
   pg_recovery_stats(osd->pg_recovery_stats),
@@ -1823,11 +1822,8 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev,
 {
   int ret;
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr(
-    new ObjectStore::Sequencer("mkfs"));
   OSDSuperblock sb;
   bufferlist sbbl;
-  C_SaferCond waiter;
 
   // if we are fed a uuid for this osd, use it.
   store->set_fsid(cct->_conf->osd_uuid);
@@ -1877,19 +1873,21 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev,
     bufferlist bl;
     encode(sb, bl);
 
+    ObjectStore::CollectionHandle ch = store->create_new_collection(
+      coll_t::meta());
     ObjectStore::Transaction t;
     t.create_collection(coll_t::meta(), 0);
     t.write(coll_t::meta(), OSD_SUPERBLOCK_GOBJECT, 0, bl.length(), bl);
-    ret = store->apply_transaction(osr.get(), std::move(t));
+    ret = store->apply_transaction(ch, std::move(t));
     if (ret) {
       derr << "OSD::mkfs: error while writing OSD_SUPERBLOCK_GOBJECT: "
           << "apply_transaction returned " << cpp_strerror(ret) << dendl;
       goto umount_store;
     }
-  }
-
-  if (!osr->flush_commit(&waiter)) {
-    waiter.wait();
+    C_SaferCond waiter;
+    if (!ch->flush_commit(&waiter)) {
+      waiter.wait();
+    }
   }
 
   ret = write_meta(cct, store, sb.cluster_fsid, sb.osd_fsid, whoami);
@@ -2536,6 +2534,8 @@ int OSD::init()
 
   dout(2) << "boot" << dendl;
 
+  service.meta_ch = store->open_collection(coll_t::meta());
+
   // initialize the daily loadavg with current 15min loadavg
   double loadavgs[3];
   if (getloadavg(loadavgs, 3) == 3) {
@@ -2645,7 +2645,7 @@ int OSD::init()
     dout(5) << "Upgrading superblock adding: " << diff << dendl;
     ObjectStore::Transaction t;
     write_superblock(t);
-    r = store->apply_transaction(service.meta_osr.get(), std::move(t));
+    r = store->apply_transaction(service.meta_ch, std::move(t));
     if (r < 0)
       goto out;
   }
@@ -2655,7 +2655,7 @@ int OSD::init()
     dout(10) << "init creating/touching snapmapper object" << dendl;
     ObjectStore::Transaction t;
     t.touch(coll_t::meta(), OSD::make_snapmapper_oid());
-    r = store->apply_transaction(service.meta_osr.get(), std::move(t));
+    r = store->apply_transaction(service.meta_ch, std::move(t));
     if (r < 0)
       goto out;
   }
@@ -3481,7 +3481,7 @@ int OSD::shutdown()
   superblock.clean_thru = osdmap->get_epoch();
   ObjectStore::Transaction t;
   write_superblock(t);
-  int r = store->apply_transaction(service.meta_osr.get(), std::move(t));
+  int r = store->apply_transaction(service.meta_ch, std::move(t));
   if (r) {
     derr << "OSD::shutdown: error writing superblock: "
         << cpp_strerror(r) << dendl;
@@ -3514,6 +3514,7 @@ int OSD::shutdown()
          ceph_abort();
        }
       }
+      p->second->ch.reset();
       p->second->unlock();
       p->second->put("PGMap");
     }
@@ -3524,6 +3525,8 @@ int OSD::shutdown()
 #endif
   cct->_conf->remove_observer(this);
 
+  service.meta_ch.reset();
+
   dout(10) << "syncing store" << dendl;
   enable_disable_fuse(true);
 
@@ -3738,13 +3741,13 @@ void OSD::clear_temp_objects()
        dout(20) << "  removing " << *p << " object " << *q << dendl;
        t.remove(*p, *q);
         if (++removed > cct->_conf->osd_target_transaction_size) {
-          store->apply_transaction(service.meta_osr.get(), std::move(t));
+          store->apply_transaction(service.meta_ch, std::move(t));
           t = ObjectStore::Transaction();
           removed = 0;
         }
       }
       if (removed) {
-        store->apply_transaction(service.meta_osr.get(), std::move(t));
+        store->apply_transaction(service.meta_ch, std::move(t));
       }
     }
   }
@@ -3759,8 +3762,7 @@ void OSD::recursive_remove_collection(CephContext* cct,
     coll_t(),
     make_snapmapper_oid());
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr (std::make_shared<
-                                      ObjectStore::Sequencer>("rm"));
+  ObjectStore::CollectionHandle ch = store->open_collection(tmp);
   ObjectStore::Transaction t;
   SnapMapper mapper(cct, &driver, 0, 0, 0, pgid.shard);
 
@@ -3779,18 +3781,18 @@ void OSD::recursive_remove_collection(CephContext* cct,
       ceph_abort();
     t.remove(tmp, *p);
     if (removed > cct->_conf->osd_target_transaction_size) {
-      int r = store->apply_transaction(osr.get(), std::move(t));
+      int r = store->apply_transaction(ch, std::move(t));
       assert(r == 0);
       t = ObjectStore::Transaction();
       removed = 0;
     }
   }
   t.remove_collection(tmp);
-  int r = store->apply_transaction(osr.get(), std::move(t));
+  int r = store->apply_transaction(ch, std::move(t));
   assert(r == 0);
 
   C_SaferCond waiter;
-  if (!osr->flush_commit(&waiter)) {
+  if (!ch->flush_commit(&waiter)) {
     waiter.wait();
   }
 }
@@ -3888,7 +3890,6 @@ PG *OSD::_create_lock_pg(
   PG *pg = _open_lock_pg(createmap, pgid, true);
 
   service.init_splits_between(pgid, pg->get_osdmap(), service.get_osdmap());
-
   pg->init(
     role,
     up,
@@ -3900,6 +3901,8 @@ PG *OSD::_create_lock_pg(
     backfill,
     &t);
 
+  pg->ch = store->create_new_collection(pg->coll);
+
   dout(7) << "_create_lock_pg " << *pg << dendl;
   return pg;
 }
@@ -5088,7 +5091,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
       val.append(valstr);
       newattrs[key] = val;
       t.omap_setkeys(coll_t(pgid), ghobject_t(obj), newattrs);
-      r = store->apply_transaction(service->meta_osr.get(), std::move(t));
+      r = store->apply_transaction(service->meta_ch, std::move(t));
       if (r < 0)
         ss << "error=" << r;
       else
@@ -5100,7 +5103,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
 
       keys.insert(key);
       t.omap_rmkeys(coll_t(pgid), ghobject_t(obj), keys);
-      r = store->apply_transaction(service->meta_osr.get(), std::move(t));
+      r = store->apply_transaction(service->meta_ch, std::move(t));
       if (r < 0)
         ss << "error=" << r;
       else
@@ -5112,7 +5115,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
       cmd_getval(service->cct, cmdmap, "header", headerstr);
       newheader.append(headerstr);
       t.omap_setheader(coll_t(pgid), ghobject_t(obj), newheader);
-      r = store->apply_transaction(service->meta_osr.get(), std::move(t));
+      r = store->apply_transaction(service->meta_ch, std::move(t));
       if (r < 0)
         ss << "error=" << r;
       else
@@ -5135,7 +5138,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
       int64_t trunclen;
       cmd_getval(service->cct, cmdmap, "len", trunclen);
       t.truncate(coll_t(pgid), ghobject_t(obj), trunclen);
-      r = store->apply_transaction(service->meta_osr.get(), std::move(t));
+      r = store->apply_transaction(service->meta_ch, std::move(t));
       if (r < 0)
        ss << "error=" << r;
       else
@@ -6044,9 +6047,6 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
     cmd_getval(cct, cmdmap, "object_size", osize, (int64_t)0);
     cmd_getval(cct, cmdmap, "object_num", onum, (int64_t)0);
 
-    ceph::shared_ptr<ObjectStore::Sequencer> osr (std::make_shared<
-                                        ObjectStore::Sequencer>("bench"));
-
     uint32_t duration = cct->_conf->osd_bench_duration;
 
     if (bsize > (int64_t) cct->_conf->osd_bench_max_block_size) {
@@ -6122,7 +6122,7 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
        hobject_t soid(sobject_t(oid, 0));
        ObjectStore::Transaction t;
        t.write(coll_t(), ghobject_t(soid), 0, osize, bl);
-       store->queue_transaction(osr.get(), std::move(t), NULL);
+       store->queue_transaction(service.meta_ch, std::move(t), NULL);
        cleanupt.remove(coll_t(), ghobject_t(soid));
       }
     }
@@ -6135,7 +6135,7 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
 
     {
       C_SaferCond waiter;
-      if (!osr->flush_commit(&waiter)) {
+      if (!service.meta_ch->flush_commit(&waiter)) {
        waiter.wait();
       }
     }
@@ -6154,24 +6154,24 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
       hobject_t soid(sobject_t(oid, 0));
       ObjectStore::Transaction t;
       t.write(coll_t::meta(), ghobject_t(soid), offset, bsize, bl);
-      store->queue_transaction(osr.get(), std::move(t), NULL);
+      store->queue_transaction(service.meta_ch, std::move(t), NULL);
       if (!onum || !osize)
        cleanupt.remove(coll_t::meta(), ghobject_t(soid));
     }
 
     {
       C_SaferCond waiter;
-      if (!osr->flush_commit(&waiter)) {
+      if (!service.meta_ch->flush_commit(&waiter)) {
        waiter.wait();
       }
     }
     utime_t end = ceph_clock_now();
 
     // clean up
-    store->queue_transaction(osr.get(), std::move(cleanupt), NULL);
+    store->queue_transaction(service.meta_ch, std::move(cleanupt), NULL);
     {
       C_SaferCond waiter;
-      if (!osr->flush_commit(&waiter)) {
+      if (!service.meta_ch->flush_commit(&waiter)) {
        waiter.wait();
       }
     }
@@ -7114,7 +7114,7 @@ void OSD::trim_maps(epoch_t oldest, int nreceived, bool skip_maps)
     if (num >= cct->_conf->osd_target_transaction_size && num >= nreceived) {
       service.publish_superblock(superblock);
       write_superblock(t);
-      int tr = store->queue_transaction(service.meta_osr.get(), std::move(t), nullptr);
+      int tr = store->queue_transaction(service.meta_ch, std::move(t), nullptr);
       assert(tr == 0);
       num = 0;
       if (!skip_maps) {
@@ -7130,7 +7130,7 @@ void OSD::trim_maps(epoch_t oldest, int nreceived, bool skip_maps)
   if (num > 0) {
     service.publish_superblock(superblock);
     write_superblock(t);
-    int tr = store->queue_transaction(service.meta_osr.get(), std::move(t), nullptr);
+    int tr = store->queue_transaction(service.meta_ch, std::move(t), nullptr);
     assert(tr == 0);
   }
   // we should not remove the cached maps
@@ -7387,7 +7387,7 @@ void OSD::handle_osd_map(MOSDMap *m)
   // superblock and commit
   write_superblock(t);
   store->queue_transaction(
-    service.meta_osr.get(),
+    service.meta_ch,
     std::move(t),
     new C_OnMapApply(&service, std::move(pinned_maps), last),
     new C_OnMapCommit(this, start, last, m), 0);
@@ -7719,7 +7719,7 @@ void OSD::check_osdmap_features()
       superblock.compat_features.incompat.insert(CEPH_OSD_FEATURE_INCOMPAT_SHARDS);
       ObjectStore::Transaction t;
       write_superblock(t);
-      int err = store->queue_transaction(service.meta_osr.get(), std::move(t), NULL);
+      int err = store->queue_transaction(service.meta_ch, std::move(t), NULL);
       assert(err == 0);
     }
   }
@@ -8091,6 +8091,7 @@ void OSD::split_pgs(
       child,
       split_bits);
 
+    child->ch = store->create_new_collection(child->coll);
     child->finish_split_stats(*stat_iter, rctx->transaction);
     child->unlock();
   }
@@ -8242,7 +8243,7 @@ void OSD::dispatch_context_transaction(PG::RecoveryCtx &ctx, PG *pg,
       ctx.on_applied->add(new C_OpenPGs(ctx.created_pgs, store, this));
     }
     int tr = store->queue_transaction(
-      pg->osr.get(),
+      pg->ch,
       std::move(*ctx.transaction), ctx.on_applied, ctx.on_safe, NULL,
       TrackedOpRef(), handle);
     delete (ctx.transaction);
@@ -8278,7 +8279,7 @@ void OSD::dispatch_context(PG::RecoveryCtx &ctx, PG *pg, OSDMapRef curmap,
       ctx.on_applied->add(new C_OpenPGs(ctx.created_pgs, store, this));
     }
     int tr = store->queue_transaction(
-      pg->osr.get(),
+      pg->ch,
       std::move(*ctx.transaction), ctx.on_applied, ctx.on_safe, NULL, TrackedOpRef(),
       handle);
     delete (ctx.transaction);
index ee94a50320708ca05aa8738b34dd6017fb36fd75..4fae60abe303a155a7f4329fd7b386867e6fb744 100644 (file)
@@ -236,7 +236,6 @@ struct C_CompleteSplits;
 struct C_OpenPGs;
 class LogChannel;
 class CephContext;
-typedef ceph::shared_ptr<ObjectStore::Sequencer> SequencerRef;
 class MOSDOp;
 
 class OSD;
@@ -245,8 +244,7 @@ class OSDService {
 public:
   OSD *osd;
   CephContext *cct;
-  SharedPtrRegistry<spg_t, ObjectStore::Sequencer> osr_registry;
-  ceph::shared_ptr<ObjectStore::Sequencer> meta_osr;
+  ObjectStore::CollectionHandle meta_ch;
   const int whoami;
   ObjectStore *&store;
   LogClient &log_client;
index 80cddeb90fb6a567cb2dfdd2fea1c2b90c5641ec..28055987727548c58429ea4c24923e75e891f753 100644 (file)
@@ -309,7 +309,6 @@ PG::PG(OSDService *o, OSDMapRef curmap,
        const PGPool &_pool, spg_t p) :
   pg_id(p),
   coll(p),
-  osr(o->osr_registry.lookup_or_create(p, (stringify(p)))),
   osd(o),
   cct(o->cct),
   osdmap_ref(curmap),
@@ -366,7 +365,6 @@ PG::PG(OSDService *o, OSDMapRef curmap,
   ss << "PG " << info.pgid;
   trace_endpoint.copy_name(ss.str());
 #endif
-  osr->shard_hint = p;
 }
 
 PG::~PG()
@@ -3054,9 +3052,8 @@ void PG::upgrade(ObjectStore *store)
   dirty_big_info = true;
   write_if_dirty(t);
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr (std::make_shared<
-                                      ObjectStore::Sequencer>("upgrade"));
-  int r = store->apply_transaction(osr.get(), std::move(t));
+  ObjectStore::CollectionHandle ch = store->open_collection(coll);
+  int r = store->apply_transaction(ch, std::move(t));
   if (r != 0) {
     derr << __func__ << ": apply_transaction returned "
         << cpp_strerror(r) << dendl;
@@ -3065,7 +3062,7 @@ void PG::upgrade(ObjectStore *store)
   assert(r == 0);
 
   C_SaferCond waiter;
-  if (!osr->flush_commit(&waiter)) {
+  if (!ch->flush_commit(&waiter)) {
     waiter.wait();
   }
 }
@@ -3309,7 +3306,7 @@ void PG::handle_pg_trim(epoch_t epoch, int from, shard_id_t shard, eversion_t tr
     pg_log.trim(trim_to, info);
     dirty_info = true;
     write_if_dirty(t);
-    int tr = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+    int tr = osd->store->queue_transaction(ch, std::move(t), NULL);
     assert(tr == 0);
   }
 }
@@ -3519,7 +3516,7 @@ void PG::read_state(ObjectStore *store)
   PG::RecoveryCtx rctx(0, 0, 0, 0, 0, new ObjectStore::Transaction);
   handle_loaded(&rctx);
   write_if_dirty(*rctx.transaction);
-  store->apply_transaction(osr.get(), std::move(*rctx.transaction));
+  store->apply_transaction(ch, std::move(*rctx.transaction));
   delete rctx.transaction;
 }
 
@@ -4104,7 +4101,7 @@ void PG::_scan_rollback_obs(
   if (!t.empty()) {
     derr << __func__ << ": queueing trans to clean up obsolete rollback objs"
         << dendl;
-    osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+    osd->store->queue_transaction(ch, std::move(t), NULL);
   }
 }
 
@@ -4184,7 +4181,7 @@ void PG::_scan_snaps(ScrubMap &smap)
                            << "...repaired";
        }
        snap_mapper.add_oid(hoid, obj_snaps, &_t);
-       r = osd->store->apply_transaction(osr.get(), std::move(t));
+       r = osd->store->apply_transaction(ch, std::move(t));
        if (r != 0) {
          derr << __func__ << ": apply_transaction got " << cpp_strerror(r)
               << dendl;
@@ -4231,7 +4228,7 @@ void PG::_repair_oinfo_oid(ScrubMap &smap)
       o.attrs[OI_ATTR] = bp;
 
       t.setattr(coll, ghobject_t(hoid), OI_ATTR, bl);
-      int r = osd->store->apply_transaction(osr.get(), std::move(t));
+      int r = osd->store->apply_transaction(ch, std::move(t));
       if (r != 0) {
        derr << __func__ << ": apply_transaction got " << cpp_strerror(r)
             << dendl;
@@ -4255,7 +4252,7 @@ int PG::build_scrub_map_chunk(
   while (pos.empty()) {
     pos.deep = deep;
     map.valid_through = info.last_update;
-    osr->flush();
+    ch->flush();
 
     // objects
     vector<ghobject_t> rollback_obs;
@@ -4603,7 +4600,7 @@ void PG::chunky_scrub(ThreadPool::TPHandle &handle)
          scrubber.cleanup_store(&t);
          scrubber.store.reset(Scrub::Store::create(osd->store, &t,
                                                    info.pgid, coll));
-         osd->store->queue_transaction(osr.get(), std::move(t), nullptr);
+         osd->store->queue_transaction(ch, std::move(t), nullptr);
        }
 
         // Don't include temporary objects when scrubbing
@@ -4662,7 +4659,7 @@ void PG::chunky_scrub(ThreadPool::TPHandle &handle)
           hobject_t start = scrubber.start;
          hobject_t candidate_end;
          vector<hobject_t> objects;
-         osr->flush();
+         ch->flush();
          ret = get_pgbackend()->objects_list_partial(
            start,
            min,
@@ -5081,7 +5078,7 @@ void PG::scrub_compare_maps()
       dout(10) << __func__ << ": updating scrub object" << dendl;
       ObjectStore::Transaction t;
       scrubber.store->flush(&t);
-      osd->store->queue_transaction(osr.get(), std::move(t), nullptr);
+      osd->store->queue_transaction(ch, std::move(t), nullptr);
     }
   }
 }
@@ -5221,7 +5218,7 @@ void PG::scrub_finish()
     ObjectStore::Transaction t;
     dirty_info = true;
     write_if_dirty(t);
-    int tr = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+    int tr = osd->store->queue_transaction(ch, std::move(t), NULL);
     assert(tr == 0);
   }
 
@@ -5521,7 +5518,7 @@ void PG::reset_interval_flush()
   
   Context *c = new QueuePeeringEvt<IntervalFlush>(
     this, get_osdmap()->get_epoch(), IntervalFlush());
-  if (!osr->flush_commit(c)) {
+  if (!ch->flush_commit(c)) {
     dout(10) << "Beginning to block outgoing recovery messages" << dendl;
     recovery_state.begin_block_outgoing();
   } else {
@@ -6205,7 +6202,7 @@ void PG::update_store_on_load()
       lderr(cct) << __func__ << " setting bit width to " << bits << dendl;
       ObjectStore::Transaction t;
       t.collection_set_bits(coll, bits);
-      osd->store->apply_transaction(osr.get(), std::move(t));
+      osd->store->apply_transaction(ch, std::move(t));
     }
   }
 }
@@ -6274,7 +6271,7 @@ void PG::_delete_some()
     dout(20) << __func__ << " deleting " << num << " objects" << dendl;
     Context *fin = new C_DeleteMore(this, e);
     osd->store->queue_transaction(
-      osr.get(),
+      ch,
       std::move(t),
       fin,
       fin);
@@ -6289,7 +6286,7 @@ void PG::_delete_some()
     t.remove_collection(coll);
     PGRef pgref(this);
     int r = osd->store->queue_transaction(
-      osd->meta_osr.get(), std::move(t),
+      osd->meta_ch, std::move(t),
       // keep pg ref around until txn completes to avoid any issues
       // with Sequencer lifecycle (seen w/ filestore).
       new ContainerContext<PGRef>(pgref),
index fe092a4ae38ce3a3ff23df45c4b620945c92c829..91431cb2c46847a42d7436041100c287120ed337 100644 (file)
@@ -251,9 +251,6 @@ public:
   const spg_t pg_id;
   const coll_t coll;
 
-  // for ordering writes
-  ceph::shared_ptr<ObjectStore::Sequencer> osr;
-
   ObjectStore::CollectionHandle ch;
 
   class RecoveryCtx;
index c3c62f01aecd289344b5c793cb6b4d1b6a530f16..36ccfbf61ede2b26824b46c2490ed6f0f6a94542 100644 (file)
@@ -1208,7 +1208,7 @@ void PrimaryLogPG::do_pg_op(OpRequestRef op)
        }
 
        hobject_t current = lower_bound;
-       osr->flush();
+       ch->flush();
        int r = pgbackend->objects_list_partial(
          current,
          list_size,
@@ -1365,7 +1365,7 @@ void PrimaryLogPG::do_pg_op(OpRequestRef op)
 
        hobject_t next;
        hobject_t current = response.handle;
-       osr->flush();
+       ch->flush();
        int r = pgbackend->objects_list_partial(
          current,
          list_size,
@@ -4097,7 +4097,7 @@ void PrimaryLogPG::do_backfill(OpRequestRef op)
       ObjectStore::Transaction t;
       dirty_info = true;
       write_if_dirty(t);
-      int tr = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+      int tr = osd->store->queue_transaction(ch, std::move(t), NULL);
       assert(tr == 0);
     }
     break;
@@ -4125,7 +4125,7 @@ void PrimaryLogPG::do_backfill_remove(OpRequestRef op)
   for (auto& p : m->ls) {
     remove_snap_mapped_object(t, p.first);
   }
-  int r = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+  int r = osd->store->queue_transaction(ch, std::move(t), NULL);
   assert(r == 0);
 }
 
@@ -10377,7 +10377,7 @@ void PrimaryLogPG::submit_log_entries(
        new OnComplete{this, rep_tid, get_osdmap()->get_epoch()});
       t.register_on_applied(
        new C_OSD_OnApplied{this, get_osdmap()->get_epoch(), info.last_update});
-      int r = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+      int r = osd->store->queue_transaction(ch, std::move(t), NULL);
       assert(r == 0);
     });
 }
@@ -11136,7 +11136,7 @@ void PrimaryLogPG::remove_missing_object(const hobject_t &soid,
         ObjectStore::Transaction t2;
         on_local_recover(soid, recovery_info, ObjectContextRef(), true, &t2);
         t2.register_on_complete(on_complete);
-        int r = osd->store->queue_transaction(osr.get(), std::move(t2), nullptr);
+        int r = osd->store->queue_transaction(ch, std::move(t2), nullptr);
         assert(r == 0);
         unlock();
        } else {
@@ -11144,7 +11144,7 @@ void PrimaryLogPG::remove_missing_object(const hobject_t &soid,
         on_complete->complete(-EAGAIN);
        }
      }));
-  int r = osd->store->queue_transaction(osr.get(), std::move(t), nullptr);
+  int r = osd->store->queue_transaction(ch, std::move(t), nullptr);
   assert(r == 0);
 }
 
@@ -11356,7 +11356,7 @@ void PrimaryLogPG::do_update_log_missing(OpRequestRef &op)
   t.register_on_applied(
     new C_OSD_OnApplied{this, get_osdmap()->get_epoch(), info.last_update});
   int tr = osd->store->queue_transaction(
-    osr.get(),
+    ch,
     std::move(t),
     nullptr);
   assert(tr == 0);
@@ -11654,7 +11654,7 @@ void PrimaryLogPG::shutdown()
   lock();
   on_shutdown();
   unlock();
-  osr->flush();
+  ch->flush();
 }
 
 void PrimaryLogPG::on_shutdown()
@@ -12268,7 +12268,7 @@ uint64_t PrimaryLogPG::recover_primary(uint64_t max, ThreadPool::TPHandle &handl
 
              ++active_pushes;
 
-             osd->store->queue_transaction(osr.get(), std::move(t),
+             osd->store->queue_transaction(ch, std::move(t),
                                            new C_OSD_AppliedRecoveredObject(this, obc),
                                            new C_OSD_CommittedPushedObject(
                                              this,
@@ -13001,7 +13001,7 @@ void PrimaryLogPG::update_range(
   if (bi->version < info.log_tail) {
     dout(10) << __func__<< ": bi is old, rescanning local backfill_info"
             << dendl;
-    osr->flush();
+    ch->flush();
     if (last_update_applied >= info.log_tail) {
       bi->version = last_update_applied;
     } else {
@@ -14967,7 +14967,7 @@ boost::statechart::result PrimaryLogPG::AwaitAsyncWork::react(const DoSnapWork&)
     ObjectStore::Transaction t;
     pg->dirty_big_info = true;
     pg->write_if_dirty(t);
-    int tr = pg->osd->store->queue_transaction(pg->osr.get(), std::move(t), NULL);
+    int tr = pg->osd->store->queue_transaction(pg->ch, std::move(t), NULL);
     assert(tr == 0);
 
     pg->share_pg_info();
index 9cceb28d1c07e8c635dfb8f75a8ee73d215fa1eb..a283fd2864e83c935a4469fdb273a9a126edbf46 100644 (file)
@@ -310,11 +310,11 @@ public:
   }
   void queue_transaction(ObjectStore::Transaction&& t,
                         OpRequestRef op) override {
-    osd->store->queue_transaction(osr.get(), std::move(t), 0, 0, 0, op);
+    osd->store->queue_transaction(ch, std::move(t), 0, 0, 0, op);
   }
   void queue_transactions(vector<ObjectStore::Transaction>& tls,
                          OpRequestRef op) override {
-    osd->store->queue_transactions(osr.get(), tls, 0, 0, 0, op, NULL);
+    osd->store->queue_transactions(ch, tls, 0, 0, 0, op, NULL);
   }
   epoch_t get_epoch() const override {
     return get_osdmap()->get_epoch();
index e93ea80fcb6cd77800feb10133189161b66c446d..8f4cb49481c1dfb2c00b78f2b6072dc1d3ab4d7a 100644 (file)
@@ -37,8 +37,7 @@
 DeterministicOpSequence::DeterministicOpSequence(ObjectStore *store,
                                                 std::string status)
   : TestObjectStoreState(store),
-    txn(0),
-    m_osr("OSR")
+    txn(0)
 {
   txn_object = hobject_t(sobject_t("txn", CEPH_NOSNAP));
 
@@ -151,10 +150,10 @@ bool DeterministicOpSequence::do_touch(rngen_t& gen)
   // Don't care about other collections if already exists
   if (!entry->check_for_obj(obj_id)) {
     bool other_found = false;
-    map<int, coll_entry_t*>::iterator it = m_collections.begin();
+    auto it = m_collections.begin();
     for (; it != m_collections.end(); ++it) {
       if (it->second->check_for_obj(obj_id)) {
-        ceph_assert(it->first != coll_id);
+        ceph_assert(it->first != entry->m_cid);
         other_found = true;
       }
     }
@@ -165,7 +164,7 @@ bool DeterministicOpSequence::do_touch(rngen_t& gen)
   }
   hobject_t *obj = entry->touch_obj(obj_id);
 
-  dout(0) << "do_touch " << entry->m_coll << "/" << obj << dendl;
+  dout(0) << "do_touch " << entry->m_cid << "/" << obj << dendl;
 
   _do_touch(entry, *obj);
   return true;
@@ -186,7 +185,7 @@ bool DeterministicOpSequence::do_remove(rngen_t& gen)
   hobject_t *obj = entry->touch_obj(obj_id);
   ceph_assert(obj);
 
-  dout(0) << "do_remove " << entry->m_coll << "/" << obj << dendl;
+  dout(0) << "do_remove " << entry->m_cid << "/" << obj << dendl;
 
   _do_remove(entry, *obj);
   hobject_t *rmobj = entry->remove_obj(obj_id);
@@ -270,7 +269,7 @@ bool DeterministicOpSequence::do_write(rngen_t& gen)
   bufferlist bl;
   _gen_random(gen, size, bl);
 
-  dout(0) << "do_write " << entry->m_coll << "/" << obj
+  dout(0) << "do_write " << entry->m_cid << "/" << obj
          << " 0~" << size << dendl;
 
   _do_write(entry, *obj, 0, bl.length(), bl);
@@ -291,7 +290,7 @@ bool DeterministicOpSequence::_prepare_clone(
   ceph_assert(entry != NULL);
 
   if (entry->m_objects.size() < 2) {
-    dout(0) << "_prepare_clone coll " << entry->m_coll
+    dout(0) << "_prepare_clone coll " << entry->m_cid
            << " doesn't have 2 or more objects" << dendl;
     return false;
   }
@@ -321,8 +320,8 @@ bool DeterministicOpSequence::do_clone(rngen_t& gen)
     return false;
   }
 
-  dout(0) << "do_clone " << entry->m_coll << "/" << orig_obj
-      << " => " << entry->m_coll << "/" << new_obj << dendl;
+  dout(0) << "do_clone " << entry->m_cid << "/" << orig_obj
+      << " => " << entry->m_cid << "/" << new_obj << dendl;
 
   _do_clone(entry, orig_obj, new_obj);
   return true;
@@ -352,9 +351,9 @@ bool DeterministicOpSequence::do_clone_range(rngen_t& gen)
   boost::uniform_int<> clone_len(1, bl.length());
   size = (size_t) clone_len(gen);
 
-  dout(0) << "do_clone_range " << entry->m_coll << "/" << orig_obj
+  dout(0) << "do_clone_range " << entry->m_cid << "/" << orig_obj
       << " (0~" << size << ")"
-      << " => " << entry->m_coll << "/" << new_obj
+      << " => " << entry->m_cid << "/" << new_obj
       << " (0)" << dendl;
   _do_write_and_clone_range(entry, orig_obj, new_obj, 0, size, 0, bl);
   return true;
@@ -369,8 +368,8 @@ bool DeterministicOpSequence::do_coll_move(rngen_t& gen)
     return false;
   }
 
-  dout(0) << "do_coll_move " << entry->m_coll << "/" << orig_obj
-        << " => " << entry->m_coll << "/" << new_obj << dendl;
+  dout(0) << "do_coll_move " << entry->m_cid << "/" << orig_obj
+        << " => " << entry->m_cid << "/" << new_obj << dendl;
   entry->remove_obj(orig_id);
 
   _do_coll_move(entry, orig_obj, new_obj);
@@ -381,9 +380,12 @@ bool DeterministicOpSequence::do_coll_move(rngen_t& gen)
 bool DeterministicOpSequence::do_coll_create(rngen_t& gen)
 {
   int i = m_collections.size();
-  coll_entry_t *entry = coll_create(i);
-  m_collections.insert(make_pair(i, entry));
-  m_collections_ids.push_back(i);
+  spg_t pgid(pg_t(i, 0), shard_id_t::NO_SHARD);
+  coll_t cid(pgid);
+  auto ch = m_store->create_new_collection(cid);
+  coll_entry_t *entry = coll_create(pgid, ch);
+  m_collections.insert(make_pair(cid, entry));
+  rebuild_id_vec();
 
   _do_coll_create(entry, 10, 10);
   
@@ -394,32 +396,32 @@ void DeterministicOpSequence::_do_coll_create(coll_entry_t *entry, uint32_t pg_n
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.create_collection(entry->m_coll, 32);
+  t.create_collection(entry->m_cid, 32);
   bufferlist hint;
   encode(pg_num, hint);
   encode(num_objs, hint);
-  t.collection_hint(entry->m_coll, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
-  dout(0) << "Give collection: " << entry->m_coll
+  t.collection_hint(entry->m_cid, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
+  dout(0) << "Give collection: " << entry->m_cid
          << " a hint, pg_num is: " << pg_num << ", num_objs is: "
          << num_objs << dendl;
 
-  m_store->apply_transaction(&m_osr, std::move(t));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_touch(coll_entry_t *entry, hobject_t& obj)
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.touch(entry->m_coll, ghobject_t(obj));
-  m_store->apply_transaction(&m_osr, std::move(t));
+  t.touch(entry->m_cid, ghobject_t(obj));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_remove(coll_entry_t *entry, hobject_t& obj)
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.remove(entry->m_coll, ghobject_t(obj));
-  m_store->apply_transaction(&m_osr, std::move(t));
+  t.remove(entry->m_cid, ghobject_t(obj));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_set_attrs(coll_entry_t *entry,
@@ -428,8 +430,8 @@ void DeterministicOpSequence::_do_set_attrs(coll_entry_t *entry,
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.omap_setkeys(entry->m_coll, ghobject_t(obj), attrs);
-  m_store->apply_transaction(&m_osr, std::move(t));
+  t.omap_setkeys(entry->m_cid, ghobject_t(obj), attrs);
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_write(coll_entry_t *entry, hobject_t& obj,
@@ -437,8 +439,8 @@ void DeterministicOpSequence::_do_write(coll_entry_t *entry, hobject_t& obj,
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.write(entry->m_coll, ghobject_t(obj), off, len, data);
-  m_store->apply_transaction(&m_osr, std::move(t));
+  t.write(entry->m_cid, ghobject_t(obj), off, len, data);
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_clone(coll_entry_t *entry, hobject_t& orig_obj,
@@ -446,8 +448,8 @@ void DeterministicOpSequence::_do_clone(coll_entry_t *entry, hobject_t& orig_obj
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.clone(entry->m_coll, ghobject_t(orig_obj), ghobject_t(new_obj));
-  m_store->apply_transaction(&m_osr, std::move(t));
+  t.clone(entry->m_cid, ghobject_t(orig_obj), ghobject_t(new_obj));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_clone_range(coll_entry_t *entry,
@@ -456,9 +458,9 @@ void DeterministicOpSequence::_do_clone_range(coll_entry_t *entry,
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.clone_range(entry->m_coll, ghobject_t(orig_obj), ghobject_t(new_obj),
+  t.clone_range(entry->m_cid, ghobject_t(orig_obj), ghobject_t(new_obj),
                srcoff, srclen, dstoff);
-  m_store->apply_transaction(&m_osr, std::move(t));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_write_and_clone_range(coll_entry_t *entry,
@@ -471,10 +473,10 @@ void DeterministicOpSequence::_do_write_and_clone_range(coll_entry_t *entry,
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.write(entry->m_coll, ghobject_t(orig_obj), srcoff, bl.length(), bl);
-  t.clone_range(entry->m_coll, ghobject_t(orig_obj), ghobject_t(new_obj),
+  t.write(entry->m_cid, ghobject_t(orig_obj), srcoff, bl.length(), bl);
+  t.clone_range(entry->m_cid, ghobject_t(orig_obj), ghobject_t(new_obj),
                srcoff, srclen, dstoff);
-  m_store->apply_transaction(&m_osr, std::move(t));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
 void DeterministicOpSequence::_do_coll_move(coll_entry_t *entry,
@@ -483,9 +485,9 @@ void DeterministicOpSequence::_do_coll_move(coll_entry_t *entry,
 {
   ObjectStore::Transaction t;
   note_txn(&t);
-  t.remove(entry->m_coll, ghobject_t(new_obj));
-  t.collection_move_rename(entry->m_coll, ghobject_t(orig_obj),
-                          entry->m_coll, ghobject_t(new_obj));
-  m_store->apply_transaction(&m_osr, std::move(t));
+  t.remove(entry->m_cid, ghobject_t(new_obj));
+  t.collection_move_rename(entry->m_cid, ghobject_t(orig_obj),
+                          entry->m_cid, ghobject_t(new_obj));
+  m_store->apply_transaction(entry->m_ch, std::move(t));
 }
 
index 92373e139290e5af176b83bd5e955d30b2f1e49b..5f45922432583199ac378636ceca1198f3e305c3 100644 (file)
@@ -52,7 +52,7 @@ class DeterministicOpSequence : public TestObjectStoreState {
   coll_t txn_coll;
   hobject_t txn_object;
 
-  ObjectStore::Sequencer m_osr;
+  ObjectStore::CollectionHandle m_ch;
   std::ofstream m_status;
 
   bool run_one_op(int op, rngen_t& gen);
index 3bdcec8f6b697e6d2ec7f517576fe4f60b5e8b78..c8126cf81ebb13c602fe905f441b58096f3f40b6 100644 (file)
@@ -158,6 +158,8 @@ bool FileStoreDiff::diff_objects(FileStore *a_store, FileStore *b_store, coll_t
     ret = true;
   }
 
+  auto a_ch = a_store->open_collection(coll);
+  auto b_ch = b_store->open_collection(coll);
   std::vector<ghobject_t>::iterator b_it = b_objects.begin();
   std::vector<ghobject_t>::iterator a_it = b_objects.begin();
   for (; b_it != b_objects.end(); ++b_it, ++a_it) {
@@ -171,13 +173,13 @@ bool FileStoreDiff::diff_objects(FileStore *a_store, FileStore *b_store, coll_t
     }
 
     struct stat b_stat, a_stat;
-    err = b_store->stat(coll, b_obj, &b_stat);
+    err = b_store->stat(b_ch, b_obj, &b_stat);
     if (err < 0) {
       cout << "diff_objects error stating B object "
              << coll.to_str() << "/" << b_obj.hobj.oid.name << std::endl;
       ret = true;
     }
-    err = a_store->stat(coll, a_obj, &a_stat);
+    err = a_store->stat(a_ch, a_obj, &a_stat);
     if (err < 0) {
       cout << "diff_objects error stating A object "
           << coll << "/" << a_obj << std::endl;
@@ -191,8 +193,8 @@ bool FileStoreDiff::diff_objects(FileStore *a_store, FileStore *b_store, coll_t
     }
 
     bufferlist a_obj_bl, b_obj_bl;
-    b_store->read(coll, b_obj, 0, b_stat.st_size, b_obj_bl);
-    a_store->read(coll, a_obj, 0, a_stat.st_size, a_obj_bl);
+    b_store->read(b_ch, b_obj, 0, b_stat.st_size, b_obj_bl);
+    a_store->read(a_ch, a_obj, 0, a_stat.st_size, a_obj_bl);
 
     if (!a_obj_bl.contents_equal(b_obj_bl)) {
       cout << "diff_objects content mismatch on "
@@ -201,13 +203,13 @@ bool FileStoreDiff::diff_objects(FileStore *a_store, FileStore *b_store, coll_t
     }
 
     std::map<std::string, bufferptr> a_obj_attrs_map, b_obj_attrs_map;
-    err = a_store->getattrs(coll, a_obj, a_obj_attrs_map);
+    err = a_store->getattrs(a_ch, a_obj, a_obj_attrs_map);
     if (err < 0) {
       cout << "diff_objects getattrs on A object " << coll << "/" << a_obj
               << " returns " << err << std::endl;
       ret = true;
     }
-    err = b_store->getattrs(coll, b_obj, b_obj_attrs_map);
+    err = b_store->getattrs(b_ch, b_obj, b_obj_attrs_map);
     if (err < 0) {
       cout << "diff_objects getattrs on B object " << coll << "/" << b_obj
               << "returns " << err << std::endl;
@@ -223,25 +225,25 @@ bool FileStoreDiff::diff_objects(FileStore *a_store, FileStore *b_store, coll_t
 
     std::map<std::string, bufferlist> a_obj_omap, b_obj_omap;
     std::set<std::string> a_omap_keys, b_omap_keys;
-    err = a_store->omap_get_keys(coll, a_obj, &a_omap_keys);
+    err = a_store->omap_get_keys(a_ch, a_obj, &a_omap_keys);
     if (err < 0) {
       cout << "diff_objects getomap on A object " << coll << "/" << a_obj
               << " returns " << err << std::endl;
       ret = true;
     }
-    err = a_store->omap_get_values(coll, a_obj, a_omap_keys, &a_obj_omap);
+    err = a_store->omap_get_values(a_ch, a_obj, a_omap_keys, &a_obj_omap);
     if (err < 0) {
       cout << "diff_objects getomap on A object " << coll << "/" << a_obj
               << " returns " << err << std::endl;
       ret = true;
     }
-    err = b_store->omap_get_keys(coll, b_obj, &b_omap_keys);
+    err = b_store->omap_get_keys(b_ch, b_obj, &b_omap_keys);
     if (err < 0) {
       cout << "diff_objects getomap on A object " << coll << "/" << b_obj
               << " returns " << err << std::endl;
       ret = true;
     }
-    err = b_store->omap_get_values(coll, b_obj, b_omap_keys, &b_obj_omap);
+    err = b_store->omap_get_values(b_ch, b_obj, b_omap_keys, &b_obj_omap);
     if (err < 0) {
       cout << "diff_objects getomap on A object " << coll << "/" << b_obj
               << " returns " << err << std::endl;
index 16490ba44ad8cee1550a70c9a2b0e39f26f5730e..7ed13c2541420c9314bda91c97b5efd81ccc8cfa 100644 (file)
@@ -73,10 +73,10 @@ void FileStoreTracker::submit_transaction(Transaction &t)
        ++i) {
     (**i)(this, &out);
   }
-  store->queue_transaction(
-    0, std::move(*out.t),
-    new OnApplied(this, in_flight),
-    new OnCommitted(this, in_flight));
+  out.t->register_on_applied(new OnApplied(this, in_flight));
+  out.t->register_on_commit(new OnCommitted(this, in_flight));
+  auto ch = store->open_collection(coll_t());
+  store->queue_transaction(ch, std::move(*out.t), nullptr);
   delete out.t;
 }
 
@@ -278,7 +278,8 @@ void FileStoreTracker::verify(const coll_t &coll, const string &obj,
   pair<uint64_t, uint64_t> valid_reads = get_valid_reads(make_pair(coll, obj));
   std::cerr << "valid_reads is " << valid_reads << std::endl;
   bufferlist contents;
-  int r = store->read(coll_t(coll),
+  auto ch = store->open_collection(coll_t(coll));
+  int r = store->read(ch,
                      ghobject_t(hobject_t(sobject_t(obj, CEPH_NOSNAP))),
                      0,
                      2*SIZE,
index 54f4639323ab3816315c3ec73e4cfe1c4eb48d5a..79c9c30f5c21ddcaf585ab616b56cd9db6b57c4e 100644 (file)
@@ -34,47 +34,49 @@ void TestObjectStoreState::init(int colls, int objs)
 {
   dout(5) << "init " << colls << " colls " << objs << " objs" << dendl;
 
-  ObjectStore::Sequencer osr(__func__);
   ObjectStore::Transaction t;
-
+  auto meta_ch = m_store->create_new_collection(coll_t::meta());
   t.create_collection(coll_t::meta(), 0);
-  m_store->apply_transaction(&osr, std::move(t));
+  m_store->apply_transaction(meta_ch, std::move(t));
 
   wait_for_ready();
 
   int baseid = 0;
   for (int i = 0; i < colls; i++) {
-    int coll_id = i;
-    coll_entry_t *entry = coll_create(coll_id);
-    dout(5) << "init create collection " << entry->m_coll.to_str()
+    spg_t pgid(pg_t(i, 0), shard_id_t::NO_SHARD);
+    coll_t cid(pgid);
+    auto ch = m_store->create_new_collection(cid);
+    coll_entry_t *entry = coll_create(pgid, ch);
+    dout(5) << "init create collection " << entry->m_cid
         << " meta " << entry->m_meta_obj << dendl;
 
     ObjectStore::Transaction *t = new ObjectStore::Transaction;
-    t->create_collection(entry->m_coll, 32);
+    t->create_collection(entry->m_cid, 32);
     bufferlist hint;
     uint32_t pg_num = colls;
     uint64_t num_objs = uint64_t(objs / colls);
     encode(pg_num, hint);
     encode(num_objs, hint);
-    t->collection_hint(entry->m_coll, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
+    t->collection_hint(entry->m_cid, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
     dout(5) << "give collection hint, number of objects per collection: " << num_objs << dendl;
-    t->touch(coll_t::meta(), entry->m_meta_obj);
+    t->touch(cid, entry->m_meta_obj);
 
     for (int i = 0; i < objs; i++) {
       hobject_t *obj = entry->touch_obj(i + baseid);
-      t->touch(entry->m_coll, ghobject_t(*obj));
+      t->touch(entry->m_cid, ghobject_t(*obj));
       ceph_assert(i + baseid == m_num_objects);
       m_num_objects++;
     }
     baseid += objs;
 
-    m_store->queue_transaction(&(entry->m_osr), std::move(*t),
-        new C_OnFinished(this));
+    t->register_on_commit(new C_OnFinished(this));
+    m_store->queue_transaction(entry->m_ch, std::move(*t), nullptr);
+
     delete t;
     inc_in_flight();
 
-    m_collections.insert(make_pair(coll_id, entry));
-    m_collections_ids.push_back(coll_id);
+    m_collections.insert(make_pair(cid, entry));
+    rebuild_id_vec();
     m_next_coll_nr++;
   }
   dout(5) << "init has " << m_in_flight.load() << "in-flight transactions" << dendl;
@@ -82,40 +84,35 @@ void TestObjectStoreState::init(int colls, int objs)
   dout(5) << "init finished" << dendl;
 }
 
-TestObjectStoreState::coll_entry_t *TestObjectStoreState::coll_create(int id)
+TestObjectStoreState::coll_entry_t *TestObjectStoreState::coll_create(
+  spg_t pgid, ObjectStore::CollectionHandle ch)
 {
-  char buf[100];
   char meta_buf[100];
-  memset(buf, 0, 100);
   memset(meta_buf, 0, 100);
-  snprintf(buf, 100, "0.%d_head", id);
-  snprintf(meta_buf, 100, "pglog_0.%d_head", id);
-  return (new coll_entry_t(id, buf, meta_buf));
+  snprintf(meta_buf, 100, "pglog_0_head");
+  return (new coll_entry_t(pgid, ch, meta_buf));
 }
 
 TestObjectStoreState::coll_entry_t*
-TestObjectStoreState::get_coll(int key, bool erase)
+TestObjectStoreState::get_coll(coll_t cid, bool erase)
 {
-  dout(5) << "get_coll id " << key << dendl;
+  dout(5) << "get_coll id " << cid << dendl;
 
   coll_entry_t *entry = NULL;
-  map<int, coll_entry_t*>::iterator it = m_collections.find(key);
+  auto it = m_collections.find(cid);
   if (it != m_collections.end()) {
     entry = it->second;
     if (erase) {
       m_collections.erase(it);
-      vector<int>::iterator cid_it = m_collections_ids.begin()+(entry->m_id);
-      dout(20) << __func__ << " removing key " << key << " coll_id " << entry->m_id
-             << " iterator's entry id " << (*cid_it) << dendl;
-      m_collections_ids.erase(cid_it);
+      rebuild_id_vec();
     }
   }
 
-  dout(5) << "get_coll id " << key;
+  dout(5) << "get_coll id " << cid;
   if (!entry)
     *_dout << " non-existent";
   else
-    *_dout << " name " << entry->m_coll.to_str();
+    *_dout << " name " << entry->m_cid;
   *_dout << dendl;
   return entry;
 }
@@ -130,8 +127,8 @@ TestObjectStoreState::get_coll_at(int pos, bool erase)
 
   assert((size_t) pos < m_collections_ids.size());
 
-  int coll_id = m_collections_ids[pos];
-  coll_entry_t *entry = m_collections[coll_id];
+  coll_t cid = m_collections_ids[pos];
+  coll_entry_t *entry = m_collections[cid];
 
   if (entry == NULL) {
     dout(5) << "get_coll_at pos " << pos << " non-existent" << dendl;
@@ -139,15 +136,12 @@ TestObjectStoreState::get_coll_at(int pos, bool erase)
   }
 
   if (erase) {
-    m_collections.erase(coll_id);
-    vector<int>::iterator it = m_collections_ids.begin()+(pos);
-    dout(20) << __func__ << " removing pos " << pos << " coll_id " << coll_id
-           << " iterator's entry id " << (*it) << dendl;
-    m_collections_ids.erase(it);
+    m_collections.erase(cid);
+    rebuild_id_vec();
   }
 
   dout(5) << "get_coll_at pos " << pos << ": "
-      << entry->m_coll << "(removed: " << erase << ")" << dendl;
+      << entry->m_cid << "(removed: " << erase << ")" << dendl;
 
   return entry;
 }
@@ -177,7 +171,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::touch_obj(int id)
 {
   map<int, hobject_t*>::iterator it = m_objects.find(id);
   if (it != m_objects.end()) {
-    dout(5) << "touch_obj coll id " << m_id
+    dout(5) << "touch_obj coll id " << m_cid
         << " name " << it->second->oid.name << dendl;
     return it->second;
   }
@@ -189,7 +183,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::touch_obj(int id)
   hobject_t *obj = new hobject_t(sobject_t(object_t(buf), CEPH_NOSNAP));
   m_objects.insert(make_pair(id, obj));
 
-  dout(5) << "touch_obj coll id " << m_id << " name " << buf << dendl;
+  dout(5) << "touch_obj coll id " << m_cid << " name " << buf << dendl;
   return obj;
 }
 
@@ -212,7 +206,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id, bool remove)
 {
   map<int, hobject_t*>::iterator it = m_objects.find(id);
   if (it == m_objects.end()) {
-    dout(5) << "get_obj coll " << m_coll.to_str()
+    dout(5) << "get_obj coll " << m_cid
         << " obj #" << id << " non-existent" << dendl;
     return NULL;
   }
@@ -221,7 +215,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id, bool remove)
   if (remove)
     m_objects.erase(it);
 
-  dout(5) << "get_obj coll " << m_coll.to_str() << " id " << id
+  dout(5) << "get_obj coll " << m_cid << " id " << id
       << ": " << obj->oid.name << "(removed: " << remove << ")" << dendl;
 
   return obj;
@@ -246,7 +240,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos,
     bool remove, int *key)
 {
   if (m_objects.empty()) {
-    dout(5) << "get_obj_at coll " << m_coll.to_str() << " pos " << pos
+    dout(5) << "get_obj_at coll " << m_cid << " pos " << pos
         << " in an empty collection" << dendl;
     return NULL;
   }
@@ -261,7 +255,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos,
   }
 
   if (ret == NULL) {
-    dout(5) << "get_obj_at coll " << m_coll.to_str() << " pos " << pos
+    dout(5) << "get_obj_at coll " << m_cid << " pos " << pos
         << " non-existent" << dendl;
     return NULL;
   }
@@ -272,7 +266,7 @@ hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos,
   if (remove)
     m_objects.erase(it);
 
-  dout(5) << "get_obj_at coll id " << m_id << " pos " << pos
+  dout(5) << "get_obj_at coll id " << m_cid << " pos " << pos
       << ": " << ret->oid.name << "(removed: " << remove << ")" << dendl;
 
   return ret;
index 4eaf76b5c30c2f417a1efad155dd7ef1a17e8358..30d65cb45dc85eb2f42c2a9d1002183246d32778 100644 (file)
@@ -25,20 +25,20 @@ typedef boost::mt11213b rngen_t;
 class TestObjectStoreState {
 public:
   struct coll_entry_t {
-    int m_id;
     spg_t m_pgid;
-    coll_t m_coll;
+    coll_t m_cid;
     ghobject_t m_meta_obj;
-    ObjectStore::Sequencer m_osr;
+    ObjectStore::CollectionHandle m_ch;
     map<int, hobject_t*> m_objects;
     int m_next_object_id;
 
-    coll_entry_t(int i, char *coll_buf, char *meta_obj_buf)
-      : m_id(i),
-       m_pgid(pg_t(i, 1), shard_id_t::NO_SHARD),
-       m_coll(m_pgid),
+    coll_entry_t(spg_t pgid, ObjectStore::CollectionHandle& ch,
+                char *meta_obj_buf)
+      : m_pgid(pgid),
+       m_cid(m_pgid),
        m_meta_obj(hobject_t(sobject_t(object_t(meta_obj_buf), CEPH_NOSNAP))),
-      m_osr(coll_buf), m_next_object_id(0) {
+       m_ch(ch),
+       m_next_object_id(0) {
     }
     ~coll_entry_t();
 
@@ -58,8 +58,8 @@ public:
 
  protected:
   boost::shared_ptr<ObjectStore> m_store;
-  map<int, coll_entry_t*> m_collections;
-  vector<int> m_collections_ids;
+  map<coll_t, coll_entry_t*> m_collections;
+  vector<coll_t> m_collections_ids;
   int m_next_coll_nr;
   int m_num_objs_per_coll;
   int m_num_objects;
@@ -69,6 +69,14 @@ public:
   Mutex m_finished_lock;
   Cond m_finished_cond;
 
+  void rebuild_id_vec() {
+    m_collections_ids.clear();
+    m_collections_ids.reserve(m_collections.size());
+    for (auto& i : m_collections) {
+      m_collections_ids.push_back(i.first);
+    }
+  }
+
   void wait_for_ready() {
     Mutex::Locker locker(m_finished_lock);
     while ((m_max_in_flight > 0) && (m_in_flight >= m_max_in_flight))
@@ -88,7 +96,7 @@ public:
     m_num_objs_per_coll = val;
   }
 
-  coll_entry_t *get_coll(int key, bool erase = false);
+  coll_entry_t *get_coll(coll_t cid, bool erase = false);
   coll_entry_t *get_coll_at(int pos, bool erase = false);
   int get_next_pool_id() { return m_next_pool++; }
 
@@ -104,7 +112,7 @@ public:
     m_store.reset(store);
   }
   ~TestObjectStoreState() { 
-    map<int, coll_entry_t*>::iterator it = m_collections.begin();
+    auto it = m_collections.begin();
     while (it != m_collections.end()) {
       if (it->second)
        delete it->second;
@@ -125,7 +133,7 @@ public:
     return --m_in_flight;
   }
 
-  coll_entry_t *coll_create(int id);
+  coll_entry_t *coll_create(spg_t pgid, ObjectStore::CollectionHandle ch);
 
   class C_OnFinished: public Context {
    protected:
index a50972a4b8150991c8ffdc580b5457e90437429a..5d4ac0726114423503bfc22a7b8e510aebc410e9 100644 (file)
@@ -88,14 +88,14 @@ static bool bl_eq(bufferlist& expected, bufferlist& actual)
 template <typename T>
 int apply_transaction(
   T &store,
-  ObjectStore::Sequencer *osr,
+  ObjectStore::CollectionHandle ch,
   ObjectStore::Transaction &&t) {
   if (rand() % 2) {
     ObjectStore::Transaction t2;
     t2.append(t);
-    return store->apply_transaction(osr, std::move(t2));
+    return store->apply_transaction(ch, std::move(t2));
   } else {
-    return store->apply_transaction(osr, std::move(t));
+    return store->apply_transaction(ch, std::move(t));
   }
 }
 
@@ -280,29 +280,31 @@ TEST_P(StoreTest, TrivialRemount) {
 }
 
 TEST_P(StoreTest, SimpleRemount) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
   ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
   bufferlist bl;
   bl.append("1234512345");
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     cerr << "create collection + write" << std::endl;
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.write(cid, hoid, 0, bl.length(), bl);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
+  ch.reset();
   r = store->umount();
   ASSERT_EQ(0, r);
   r = store->mount();
   ASSERT_EQ(0, r);
+  ch = store->open_collection(cid);
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid2, 0, bl.length(), bl);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -311,17 +313,19 @@ TEST_P(StoreTest, SimpleRemount) {
     t.remove(cid, hoid2);
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
+  ch.reset();
   r = store->umount();
   ASSERT_EQ(0, r);
   r = store->mount();
   ASSERT_EQ(0, r);
+  ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     bool exists = store->exists(cid, hoid);
     ASSERT_TRUE(!exists);
@@ -330,17 +334,17 @@ TEST_P(StoreTest, SimpleRemount) {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, IORemount) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   bufferlist bl;
   bl.append("1234512345");
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     cerr << "create collection + objects" << std::endl;
     ObjectStore::Transaction t;
@@ -349,7 +353,7 @@ TEST_P(StoreTest, IORemount) {
       ghobject_t hoid(hobject_t(sobject_t("Object " + stringify(n), CEPH_NOSNAP)));
       t.write(cid, hoid, 0, bl.length(), bl);
     }
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   // overwrites
@@ -359,10 +363,11 @@ TEST_P(StoreTest, IORemount) {
       ObjectStore::Transaction t;
       ghobject_t hoid(hobject_t(sobject_t("Object " + stringify(n), CEPH_NOSNAP)));
       t.write(cid, hoid, 1, bl.length(), bl);
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
   }
+  ch.reset();
   r = store->umount();
   ASSERT_EQ(0, r);
   r = store->mount();
@@ -374,13 +379,13 @@ TEST_P(StoreTest, IORemount) {
       t.remove(cid, hoid);
     }
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->open_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, UnprintableCharsName) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   string name = "funnychars_";
   for (unsigned i = 0; i < 256; ++i) {
@@ -388,14 +393,16 @@ TEST_P(StoreTest, UnprintableCharsName) {
   }
   ghobject_t oid(hobject_t(sobject_t(name, CEPH_NOSNAP)));
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     cerr << "create collection + object" << std::endl;
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, oid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
+  ch.reset();
   r = store->umount();
   ASSERT_EQ(0, r);
   r = store->mount();
@@ -405,22 +412,23 @@ TEST_P(StoreTest, UnprintableCharsName) {
     ObjectStore::Transaction t;
     t.remove(cid, oid);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->open_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, FiemapEmpty) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   int r = 0;
   ghobject_t oid(hobject_t(sobject_t("fiemap_object", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, oid);
     t.truncate(cid, oid, 100000);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -438,13 +446,12 @@ TEST_P(StoreTest, FiemapEmpty) {
     t.remove(cid, oid);
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, FiemapHoles) {
-  ObjectStore::Sequencer osr("test");
   const uint64_t MAX_EXTENTS = 4000;
   const uint64_t SKIP_STEP = 65536;
   coll_t cid;
@@ -452,13 +459,14 @@ TEST_P(StoreTest, FiemapHoles) {
   ghobject_t oid(hobject_t(sobject_t("fiemap_object", CEPH_NOSNAP)));
   bufferlist bl;
   bl.append("foo");
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, oid);
     for (uint64_t i = 0; i < MAX_EXTENTS; i++)
       t.write(cid, oid, SKIP_STEP * i, 3, bl);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -510,81 +518,86 @@ TEST_P(StoreTest, FiemapHoles) {
     t.remove(cid, oid);
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SimpleMetaColTest) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   int r = 0;
   {
+    auto ch = store->create_new_collection(cid);
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "create collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->open_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
+    auto ch = store->create_new_collection(cid);
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "add collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->open_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SimplePGColTest) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid(spg_t(pg_t(1,2), shard_id_t::NO_SHARD));
   int r = 0;
   {
     ObjectStore::Transaction t;
+    auto ch = store->create_new_collection(cid);
     t.create_collection(cid, 4);
     cerr << "create collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->open_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 4);
     cerr << "add collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->create_new_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    auto ch = store->open_collection(cid);
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SimpleColPreHashTest) {
-  ObjectStore::Sequencer osr("test");
   // Firstly we will need to revert the value making sure
   // collection hint actually works
   int merge_threshold = g_ceph_context->_conf->filestore_merge_threshold;
@@ -606,6 +619,7 @@ TEST_P(StoreTest, SimpleColPreHashTest) {
 
   coll_t cid(spg_t(pg_t(pg_id, 15), shard_id_t::NO_SHARD));
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     // Create a collection along with a hint
     ObjectStore::Transaction t;
@@ -616,7 +630,7 @@ TEST_P(StoreTest, SimpleColPreHashTest) {
     encode(expected_num_objs, hint);
     t.collection_hint(cid, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
     cerr << "collection hint" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -624,7 +638,7 @@ TEST_P(StoreTest, SimpleColPreHashTest) {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "remove collection" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   // Revert the config change so that it does not affect the split/merge tests
@@ -636,15 +650,15 @@ TEST_P(StoreTest, SimpleColPreHashTest) {
 }
 
 TEST_P(StoreTest, SmallBlockWrites) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist a;
@@ -666,7 +680,7 @@ TEST_P(StoreTest, SmallBlockWrites) {
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 0, 0x1000, a);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in, exp;
@@ -678,7 +692,7 @@ TEST_P(StoreTest, SmallBlockWrites) {
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 0x1000, 0x1000, b);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in, exp;
@@ -691,7 +705,7 @@ TEST_P(StoreTest, SmallBlockWrites) {
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 0x3000, 0x1000, c);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in, exp;
@@ -706,7 +720,7 @@ TEST_P(StoreTest, SmallBlockWrites) {
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 0x2000, 0x1000, a);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in, exp;
@@ -721,7 +735,7 @@ TEST_P(StoreTest, SmallBlockWrites) {
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 0, 0x1000, c);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -739,13 +753,12 @@ TEST_P(StoreTest, SmallBlockWrites) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, BufferCacheReadTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
@@ -754,11 +767,12 @@ TEST_P(StoreTest, BufferCacheReadTest) {
     r = store->read(cid, hoid, 0, 5, in);
     ASSERT_EQ(-ENOENT, r);
   }
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -768,7 +782,7 @@ TEST_P(StoreTest, BufferCacheReadTest) {
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     exists = store->exists(cid, hoid);
@@ -781,7 +795,7 @@ TEST_P(StoreTest, BufferCacheReadTest) {
     t.write(cid, hoid, 0, 5, bl);
     t.write(cid, hoid, 10, 5, bl);
     cerr << "TwinWrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, 15, newdata);
@@ -802,7 +816,7 @@ TEST_P(StoreTest, BufferCacheReadTest) {
     t.write(cid, hoid, 0, 5, bl);
     t.write(cid, hoid, 10, 5, bl);
     cerr << "TwinWrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, 15, newdata);
@@ -823,7 +837,7 @@ TEST_P(StoreTest, BufferCacheReadTest) {
 
     t.write(cid, hoid, 20, bl2.length(), bl2);
     cerr << "Append" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, 30, newdata);
@@ -851,7 +865,7 @@ TEST_P(StoreTest, BufferCacheReadTest) {
     t.write(cid, hoid, 1, bl.length(), bl);
     t.write(cid, hoid, 13, bl3.length(), bl3);
     cerr << "TripleWrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, 40, newdata);
@@ -872,7 +886,6 @@ TEST_P(StoreTest, BufferCacheReadTest) {
 
 void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
 {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
@@ -881,11 +894,12 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     r = store->read(cid, hoid, 0, 5, in);
     ASSERT_EQ(-ENOENT, r);
   }
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -895,7 +909,7 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     exists = store->exists(cid, hoid);
@@ -911,7 +925,7 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     bl.append(data);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "CompressibleData (4xAU) Write" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, data.size() , newdata);
@@ -958,7 +972,7 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     bl.append(data2);
     t.write(cid, hoid, 0x8000, bl.length(), bl);
     cerr << "CompressibleData partial overwrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, 0x10000, newdata);
@@ -997,7 +1011,7 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     bl.append(data2);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "CompressibleData partial overwrite, two extents overlapped, single one to be removed" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0, 0x3e000 - 1, newdata);
@@ -1035,7 +1049,7 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     bl.append(data);
     t.write(cid, hoid, 0x3f000-1, bl.length(), bl);
     cerr << "Small chunk partial overwrite, two extents overlapped, single one to be removed" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 0x3e000, 0x2000, newdata);
@@ -1051,12 +1065,14 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     cerr << "Cleaning object" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   //force fsck
+  ch.reset();
   EXPECT_EQ(store->umount(), 0);
   EXPECT_EQ(store->mount(), 0);
+  ch = store->open_collection(cid);
   auto orig_min_blob_size = g_conf->bluestore_compression_min_blob_size;
   {
     g_conf->set_val("bluestore_compression_min_blob_size", "262144");
@@ -1070,19 +1086,20 @@ void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
     bl.append(data);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "CompressibleData large blob" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   //force fsck
+  ch.reset();
   EXPECT_EQ(store->umount(), 0);
   EXPECT_EQ(store->mount(), 0);
-
+  ch = store->open_collection(cid);
   {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_conf->set_val("bluestore_compression_min_blob_size", stringify(orig_min_blob_size));
@@ -1112,7 +1129,6 @@ TEST_P(StoreTest, CompressionTest) {
 }
 
 TEST_P(StoreTest, SimpleObjectTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
@@ -1121,11 +1137,12 @@ TEST_P(StoreTest, SimpleObjectTest) {
     r = store->read(cid, hoid, 0, 5, in);
     ASSERT_EQ(-ENOENT, r);
   }
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1135,7 +1152,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     exists = store->exists(cid, hoid);
@@ -1146,7 +1163,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     t.remove(cid, hoid);
     t.touch(cid, hoid);
     cerr << "Remove then create" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1157,7 +1174,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     t.remove(cid, hoid);
     t.write(cid, hoid, 0, 5, bl);
     cerr << "Remove then create" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in;
@@ -1173,7 +1190,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     exp.append(bl);
     t.write(cid, hoid, 5, 5, bl);
     cerr << "Append" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in;
@@ -1188,7 +1205,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     exp = bl;
     t.write(cid, hoid, 0, 10, bl);
     cerr << "Full overwrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in;
@@ -1202,7 +1219,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     bl.append("abcde");
     t.write(cid, hoid, 3, 5, bl);
     cerr << "Partial overwrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in, exp;
@@ -1220,7 +1237,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
       t.truncate(cid, hoid, 0);
       t.write(cid, hoid, 5, 5, bl);
       cerr << "Truncate + hole" << std::endl;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     {
@@ -1229,7 +1246,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
       bl.append("abcde");
       t.write(cid, hoid, 0, 5, bl);
       cerr << "Reverse fill-in" << std::endl;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
 
@@ -1246,7 +1263,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     bl.append("abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234");
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "larger overwrite" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist in;
@@ -1277,7 +1294,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
       t.truncate(cid, hoid, 0);
       t.write(cid, hoid, 0x1000-1, bl.length(), bl);
       cerr << "Write unaligned csum, stage 1" << std::endl;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
 
@@ -1299,7 +1316,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
       bl.append(s3);
       t.write(cid, hoid, 1, bl.length(), bl);
       cerr << "Write unaligned csum, stage 2" << std::endl;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     in.clear();
@@ -1322,7 +1339,7 @@ TEST_P(StoreTest, SimpleObjectTest) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
@@ -1339,7 +1356,6 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
   g_conf->apply_changes(NULL);
   int r;
 
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
   ghobject_t hoid2 = hoid;
@@ -1349,11 +1365,12 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     r = store->read(cid, hoid, 0, 5, in);
     ASSERT_EQ(-ENOENT, r);
   }
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1363,7 +1380,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     exists = store->exists(cid, hoid);
@@ -1378,8 +1395,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(g_conf->bluestore_block_size, statfs.total);
     ASSERT_TRUE(statfs.available > 0u && statfs.available < g_conf->bluestore_block_size);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
@@ -1387,7 +1406,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     bl.append("abcde");
     t.write(cid, hoid, 0, 5, bl);
     cerr << "Append 5 bytes" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1399,8 +1418,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0, statfs.compressed_original);
     ASSERT_EQ(0, statfs.compressed_allocated);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
@@ -1409,7 +1430,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     bl.append(s);
     t.write(cid, hoid, 0x10000, bl.length(), bl);
     cerr << "Append 0x30000 compressible bytes" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1421,15 +1442,17 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0x20000, statfs.compressed_original);
     ASSERT_EQ(statfs.compressed_allocated, 0x10000);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
     t.zero(cid, hoid, 1, 3);
     t.zero(cid, hoid, 0x20000, 9);
     cerr << "Punch hole at 1~3, 0x20000~9" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1441,8 +1464,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0x20000 - 9, statfs.compressed_original);
     ASSERT_EQ(statfs.compressed_allocated, 0x10000);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
@@ -1452,7 +1477,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     t.write(cid, hoid, 1, bl.length(), bl);
     t.write(cid, hoid, 0x10001, bl.length(), bl);
     cerr << "Overwrite first and second(compressible) extents" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1464,8 +1489,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0x20000 - 9 - 0x1000, statfs.compressed_original);
     ASSERT_EQ(statfs.compressed_allocated, 0x10000);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
@@ -1476,7 +1503,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     t.write(cid, hoid, 0x20000, bl.length(), bl);
     t.write(cid, hoid, 0x30000, bl.length(), bl);
     cerr << "Overwrite compressed extent with 3 uncompressible ones" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1488,14 +1515,16 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0, statfs.compressed_original);
     ASSERT_EQ(0, statfs.compressed_allocated);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
     t.zero(cid, hoid, 0, 0x40000);
     cerr << "Zero object" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     struct store_statfs_t statfs;
     int r = store->statfs(&statfs);
@@ -1506,8 +1535,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0u, statfs.compressed);
     ASSERT_EQ(0u, statfs.compressed_allocated);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     ObjectStore::Transaction t;
@@ -1519,7 +1550,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     bl.append(s.substr(0, 0x10000-2));
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "Yet another compressible write" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     struct store_statfs_t statfs;
     r = store->statfs(&statfs);
@@ -1530,8 +1561,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ASSERT_EQ(0x20000, statfs.compressed_original);
     ASSERT_EQ(0x10000, statfs.compressed_allocated);
     //force fsck
+    ch.reset();
     EXPECT_EQ(store->umount(), 0);
     EXPECT_EQ(store->mount(), 0);
+    ch = store->open_collection(cid);
   }
   {
     struct store_statfs_t statfs;
@@ -1541,7 +1574,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     ObjectStore::Transaction t;
     t.clone(cid, hoid, hoid2);
     cerr << "Clone compressed objecte" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     struct store_statfs_t statfs2;
     r = store->statfs(&statfs2);
@@ -1559,7 +1592,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
     t.remove(cid, hoid2);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1581,15 +1614,15 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     return;
   StartDeferred(0x10000);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1599,7 +1632,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     exists = store->exists(cid, hoid);
@@ -1625,7 +1658,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     t.write(cid, hoid, 0, bl.length(), bl);
     t.zero(cid, hoid, 0x10000, 0x10000);
     cerr << "Append 3*0x10000 bytes and punch a hole 0x10000~10000" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1657,8 +1690,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     newdata.clear();
   }
   //force fsck
+  ch.reset();
   EXPECT_EQ(store->umount(), 0);
   EXPECT_EQ(store->mount(), 0);
+  ch = store->open_collection(cid);
 
   {
     ObjectStore::Transaction t;
@@ -1667,7 +1702,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     bl.append(data2);
     t.write(cid, hoid, 0x20000, bl.length(), bl);
     cerr << "Write 3 bytes after the hole" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1688,8 +1723,10 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     newdata.clear();
   }
   //force fsck
+  ch.reset();
   EXPECT_EQ(store->umount(), 0);
   EXPECT_EQ(store->mount(), 0);
+  ch = store->open_collection(cid);
 
   {
     ObjectStore::Transaction t;
@@ -1698,7 +1735,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     bl.append(data2);
     t.write(cid, hoid, 0x10000+1, bl.length(), bl);
     cerr << "Write 3 bytes to the hole" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1729,7 +1766,7 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
     t.zero(cid, hoid, 0, 0x10000);
     t.zero(cid, hoid, 0x20000, 0x10000);
     cerr << "Rewrite an object and create two holes at the begining and the end" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1751,15 +1788,17 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
   }
 
   //force fsck
+  ch.reset();
   EXPECT_EQ(store->umount(), 0);
   EXPECT_EQ(store->mount(), 0);
+  ch = store->open_collection(cid);
 
   {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     struct store_statfs_t statfs;
@@ -1775,16 +1814,16 @@ TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
 #endif
 
 TEST_P(StoreTest, ManySmallWrite) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
   ghobject_t b(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -1794,13 +1833,13 @@ TEST_P(StoreTest, ManySmallWrite) {
   for (int i=0; i<100; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, a, i*4096, 4096, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   for (int i=0; i<100; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, b, (rand() % 1024)*4096, 4096, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1809,21 +1848,21 @@ TEST_P(StoreTest, ManySmallWrite) {
     t.remove(cid, b);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, MultiSmallWriteSameBlock) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -1839,7 +1878,7 @@ TEST_P(StoreTest, MultiSmallWriteSameBlock) {
     u.write(cid, a, 10, 5, bl, 0);
     u.write(cid, a, 7000, 5, bl, 0);
     vector<ObjectStore::Transaction> v = {t, u};
-    store->queue_transactions(&osr, v, nullptr, &c);
+    store->queue_transactions(ch, v, nullptr, &c);
   }
   {
     ObjectStore::Transaction t, u;
@@ -1850,7 +1889,7 @@ TEST_P(StoreTest, MultiSmallWriteSameBlock) {
     u.write(cid, a, 610, 5, bl, 0);
     u.write(cid, a, 11000, 5, bl, 0);
     vector<ObjectStore::Transaction> v = {t, u};
-    store->queue_transactions(&osr, v, nullptr, &d);
+    store->queue_transactions(ch, v, nullptr, &d);
   }
   c.wait();
   d.wait();
@@ -1864,28 +1903,28 @@ TEST_P(StoreTest, MultiSmallWriteSameBlock) {
     t.remove(cid, a);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SmallSkipFront) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.touch(cid, a);
     t.truncate(cid, a, 3000);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1895,7 +1934,7 @@ TEST_P(StoreTest, SmallSkipFront) {
     bl.append(bp);
     ObjectStore::Transaction t;
     t.write(cid, a, 4096, 4096, bl);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -1911,21 +1950,21 @@ TEST_P(StoreTest, SmallSkipFront) {
     t.remove(cid, a);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, AppendDeferredVsTailCache) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("fooo", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   unsigned min_alloc = g_conf->bluestore_min_alloc_size;
@@ -1939,16 +1978,18 @@ TEST_P(StoreTest, AppendDeferredVsTailCache) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, 0, bla.length(), bla, 0);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
   // force cached tail to clear ...
   {
+    ch.reset();
     int r = store->umount();
     ASSERT_EQ(0, r);
     r = store->mount();
     ASSERT_EQ(0, r);
+    ch = store->open_collection(cid);
   }
 
   bufferptr bpb(size);
@@ -1958,7 +1999,7 @@ TEST_P(StoreTest, AppendDeferredVsTailCache) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, bla.length(), blb.length(), blb, 0);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferptr bpc(size);
@@ -1968,7 +2009,7 @@ TEST_P(StoreTest, AppendDeferredVsTailCache) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, bla.length() + blb.length(), blc.length(), blc, 0);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist final;
@@ -1986,7 +2027,7 @@ TEST_P(StoreTest, AppendDeferredVsTailCache) {
     t.remove(cid, a);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_conf->set_val("bluestore_inject_deferred_apply_delay", "0");
@@ -1994,17 +2035,17 @@ TEST_P(StoreTest, AppendDeferredVsTailCache) {
 }
 
 TEST_P(StoreTest, AppendZeroTrailingSharedBlock) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("fooo", CEPH_NOSNAP)));
   ghobject_t b = a;
   b.hobj.snap = 1;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   unsigned min_alloc = g_conf->bluestore_min_alloc_size;
@@ -2020,13 +2061,13 @@ TEST_P(StoreTest, AppendZeroTrailingSharedBlock) {
     bt.append("BADBADBADBAD");
     ObjectStore::Transaction t;
     t.write(cid, a, 0, bt.length(), bt, 0);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.truncate(cid, a, size);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -2034,7 +2075,7 @@ TEST_P(StoreTest, AppendZeroTrailingSharedBlock) {
   {
     ObjectStore::Transaction t;
     t.clone(cid, a, b);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -2046,7 +2087,7 @@ TEST_P(StoreTest, AppendZeroTrailingSharedBlock) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, min_alloc * 3, blb.length(), blb, 0);
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist final;
@@ -2069,21 +2110,21 @@ TEST_P(StoreTest, AppendZeroTrailingSharedBlock) {
     t.remove(cid, b);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = store->apply_transaction(&osr, std::move(t));
+    r = store->apply_transaction(ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SmallSequentialUnaligned) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -2094,7 +2135,7 @@ TEST_P(StoreTest, SmallSequentialUnaligned) {
   for (int i=0; i<1000; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, a, i*len, len, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -2102,22 +2143,22 @@ TEST_P(StoreTest, SmallSequentialUnaligned) {
     t.remove(cid, a);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, ManyBigWrite) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
   ghobject_t b(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -2127,28 +2168,28 @@ TEST_P(StoreTest, ManyBigWrite) {
   for (int i=0; i<10; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, a, i*4*1048586, 4*1048576, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   // aligned
   for (int i=0; i<10; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, b, (rand() % 256)*4*1048576, 4*1048576, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   // unaligned
   for (int i=0; i<10; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, b, (rand() % (256*4096))*1024, 4*1048576, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   // do some zeros
   for (int i=0; i<10; ++i) {
     ObjectStore::Transaction t;
     t.zero(cid, b, (rand() % (256*4096))*1024, 16*1048576);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -2157,20 +2198,20 @@ TEST_P(StoreTest, ManyBigWrite) {
     t.remove(cid, b);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, BigWriteBigZero) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -2184,40 +2225,40 @@ TEST_P(StoreTest, BigWriteBigZero) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, 0, bl.length(), bl);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.zero(cid, a, bl.length() / 4, bl.length() / 2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.write(cid, a, bl.length() / 2, s.length(), s);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove(cid, a);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, MiscFragmentTests) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -2227,13 +2268,13 @@ TEST_P(StoreTest, MiscFragmentTests) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, 0, 524288, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.write(cid, a, 1048576, 524288, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -2246,7 +2287,7 @@ TEST_P(StoreTest, MiscFragmentTests) {
   {
     ObjectStore::Transaction t;
     t.write(cid, a, 1048576 - 4096, 524288, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -2254,23 +2295,23 @@ TEST_P(StoreTest, MiscFragmentTests) {
     t.remove(cid, a);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
 }
 
 TEST_P(StoreTest, ZeroVsObjectSize) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   struct stat stat;
   ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist a;
@@ -2278,7 +2319,7 @@ TEST_P(StoreTest, ZeroVsObjectSize) {
   {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 0, 5, a);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_EQ(0, store->stat(cid, hoid, &stat));
@@ -2286,7 +2327,7 @@ TEST_P(StoreTest, ZeroVsObjectSize) {
   {
     ObjectStore::Transaction t;
     t.zero(cid, hoid, 1, 2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_EQ(0, store->stat(cid, hoid, &stat));
@@ -2294,7 +2335,7 @@ TEST_P(StoreTest, ZeroVsObjectSize) {
   {
     ObjectStore::Transaction t;
     t.zero(cid, hoid, 3, 200);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_EQ(0, store->stat(cid, hoid, &stat));
@@ -2302,7 +2343,7 @@ TEST_P(StoreTest, ZeroVsObjectSize) {
   {
     ObjectStore::Transaction t;
     t.zero(cid, hoid, 100000, 200);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_EQ(0, store->stat(cid, hoid, &stat));
@@ -2310,22 +2351,22 @@ TEST_P(StoreTest, ZeroVsObjectSize) {
 }
 
 TEST_P(StoreTest, ZeroLengthWrite) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     bufferlist empty;
     t.write(cid, hoid, 1048576, 0, empty);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   struct stat stat;
@@ -2339,21 +2380,21 @@ TEST_P(StoreTest, ZeroLengthWrite) {
 }
 
 TEST_P(StoreTest, ZeroLengthZero) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
   {
     ObjectStore::Transaction t;
     t.zero(cid, hoid, 1048576, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
   struct stat stat;
@@ -2367,7 +2408,6 @@ TEST_P(StoreTest, ZeroLengthZero) {
 }
 
 TEST_P(StoreTest, SimpleAttrTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("attr object 1", CEPH_NOSNAP)));
@@ -2382,13 +2422,14 @@ TEST_P(StoreTest, SimpleAttrTest) {
     r = store->getattrs(cid, hoid, aset);
     ASSERT_EQ(-ENOENT, r);
   }
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
-  osr.flush();
+  ch->flush();
   {
     bool empty;
     int r = store->collection_empty(cid, &empty);
@@ -2405,10 +2446,10 @@ TEST_P(StoreTest, SimpleAttrTest) {
     t.touch(cid, hoid);
     t.setattr(cid, hoid, "foo", val);
     t.setattr(cid, hoid, "bar", val2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
-  osr.flush();
+  ch->flush();
   {
     bool empty;
     int r = store->collection_empty(cid, &empty);
@@ -2435,20 +2476,20 @@ TEST_P(StoreTest, SimpleAttrTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SimpleListTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid(spg_t(pg_t(0, 1), shard_id_t(1)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   set<ghobject_t> all;
@@ -2464,10 +2505,10 @@ TEST_P(StoreTest, SimpleListTest) {
       t.touch(cid, hoid);
       cerr << "Creating object " << hoid << std::endl;
     }
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
-  osr.flush();
+  ch->flush();
   {
     set<ghobject_t> saw;
     vector<ghobject_t> objects;
@@ -2500,20 +2541,20 @@ TEST_P(StoreTest, SimpleListTest) {
       t.remove(cid, *p);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, ListEndTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid(spg_t(pg_t(0, 1), shard_id_t(1)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   set<ghobject_t> all;
@@ -2529,10 +2570,10 @@ TEST_P(StoreTest, ListEndTest) {
       t.touch(cid, hoid);
       cerr << "Creating object " << hoid << std::endl;
     }
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
-  osr.flush();
+  ch->flush();
   {
     ghobject_t end(hobject_t(sobject_t("object_100", CEPH_NOSNAP)),
                   ghobject_t::NO_GEN, shard_id_t(1));
@@ -2552,7 +2593,7 @@ TEST_P(StoreTest, ListEndTest) {
       t.remove(cid, *p);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
@@ -2586,15 +2627,15 @@ TEST_P(StoreTest, Sort) {
 }
 
 TEST_P(StoreTest, MultipoolListTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   int poolid = 4373;
   coll_t cid = coll_t(spg_t(pg_t(0, poolid), shard_id_t::NO_SHARD));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   set<ghobject_t> all, saw;
@@ -2612,10 +2653,10 @@ TEST_P(StoreTest, MultipoolListTest) {
       t.touch(cid, hoid);
       cerr << "Creating object " << hoid << std::endl;
     }
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
-  osr.flush();
+  ch->flush();
   {
     vector<ghobject_t> objects;
     ghobject_t next, current;
@@ -2639,20 +2680,20 @@ TEST_P(StoreTest, MultipoolListTest) {
       t.remove(cid, *p);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SimpleCloneTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP),
@@ -2670,7 +2711,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     t.write(cid, hoid, 0, small.length(), small);
     t.write(cid, hoid, 10, small.length(), small);
     cerr << "Creating object and set attr " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -2686,7 +2727,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     t.setattr(cid, hoid, "attr1", large);
     t.setattr(cid, hoid, "attr2", small);
     cerr << "Clone object and rm attr" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     r = store->read(cid, hoid, 10, 5, newdata);
@@ -2721,7 +2762,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
   }
   {
     bufferlist final;
@@ -2739,7 +2780,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     al.append(a);
     final.append(a);
     t.write(cid, hoid, pl.length(), a.length(), al);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     bufferlist rl;
     ASSERT_EQ((int)final.length(),
@@ -2750,7 +2791,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
   }
   {
     bufferlist final;
@@ -2771,7 +2812,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     al.append(a);
     final.append(a);
     t.write(cid, hoid, pl.length() + z.length(), a.length(), al);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     bufferlist rl;
     ASSERT_EQ((int)final.length(),
@@ -2782,7 +2823,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
   }
   {
     bufferlist final;
@@ -2803,7 +2844,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     al.append(a);
     final.append(a);
     t.write(cid, hoid, 17000, a.length(), al);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
     bufferlist rl;
     ASSERT_EQ((int)final.length(),
              store->read(cid, hoid, 0, final.length(), rl));
@@ -2817,7 +2858,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
   }
   {
     bufferptr p(1048576);
@@ -2832,7 +2873,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     bufferlist al;
     al.append(a);
     t.write(cid, hoid, a.length(), a.length(), al);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
     bufferlist rl;
     bufferlist final;
     final.substr_of(pl, 0, al.length());
@@ -2852,7 +2893,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
   }
   {
     bufferptr p(65536);
@@ -2867,7 +2908,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     bufferlist al;
     al.append(a);
     t.write(cid, hoid, 32768, a.length(), al);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
     bufferlist rl;
     bufferlist final;
     final.substr_of(pl, 0, 32768);
@@ -2887,7 +2928,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
   }
   {
     bufferptr p(65536);
@@ -2902,7 +2943,7 @@ TEST_P(StoreTest, SimpleCloneTest) {
     bufferlist al;
     al.append(a);
     t.write(cid, hoid, 33768, a.length(), al);
-    ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+    ASSERT_EQ(0, apply_transaction(store, ch, std::move(t)));
     bufferlist rl;
     bufferlist final;
     final.substr_of(pl, 0, 33768);
@@ -2927,21 +2968,23 @@ TEST_P(StoreTest, SimpleCloneTest) {
   //
   if (string(GetParam()) != "filestore") { 
     //verify if non-empty collection is properly handled after store reload
+    ch.reset();
     r = store->umount();
     ASSERT_EQ(r, 0);
     r = store->mount();
     ASSERT_EQ(r, 0);
+    ch = store->open_collection(cid);
 
     ObjectStore::Transaction t;
     t.remove_collection(cid);
     cerr << "Invalid rm coll" << std::endl;
     PrCtl unset_dumpable;
-    EXPECT_DEATH(apply_transaction(store, &osr, std::move(t)), "");
+    EXPECT_DEATH(apply_transaction(store, ch, std::move(t)), "");
   }
   {
     ObjectStore::Transaction t;
     t.touch(cid, hoid3); //new record in db
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   //See comment above for "filestore" check explanation.
@@ -2949,16 +2992,18 @@ TEST_P(StoreTest, SimpleCloneTest) {
     ObjectStore::Transaction t;
     //verify if non-empty collection is properly handled when there are some pending removes and live records in db
     cerr << "Invalid rm coll again" << std::endl;
+    ch.reset();
     r = store->umount();
     ASSERT_EQ(r, 0);
     r = store->mount();
     ASSERT_EQ(r, 0);
+    ch = store->open_collection(cid);
 
     t.remove(cid, hoid);
     t.remove(cid, hoid2);
     t.remove_collection(cid);
     PrCtl unset_dumpable;
-    EXPECT_DEATH(apply_transaction(store, &osr, std::move(t)), "");
+    EXPECT_DEATH(apply_transaction(store, ch, std::move(t)), "");
   }
   {
     ObjectStore::Transaction t;
@@ -2967,20 +3012,20 @@ TEST_P(StoreTest, SimpleCloneTest) {
     t.remove(cid, hoid3);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, OmapSimple) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid(hobject_t(sobject_t("omap_obj", CEPH_NOSNAP),
@@ -2998,7 +3043,7 @@ TEST_P(StoreTest, OmapSimple) {
     t.omap_setkeys(cid, hoid, km);
     t.omap_setheader(cid, hoid, header);
     cerr << "Creating object and set omap " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   // get header, keys
@@ -3035,20 +3080,20 @@ TEST_P(StoreTest, OmapSimple) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, OmapCloneTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP),
@@ -3066,7 +3111,7 @@ TEST_P(StoreTest, OmapCloneTest) {
     t.omap_setkeys(cid, hoid, km);
     t.omap_setheader(cid, hoid, header);
     cerr << "Creating object and set omap " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP),
@@ -3075,7 +3120,7 @@ TEST_P(StoreTest, OmapCloneTest) {
     ObjectStore::Transaction t;
     t.clone(cid, hoid, hoid2);
     cerr << "Clone object" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -3091,20 +3136,20 @@ TEST_P(StoreTest, OmapCloneTest) {
     t.remove(cid, hoid2);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, SimpleCloneRangeTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
@@ -3115,7 +3160,7 @@ TEST_P(StoreTest, SimpleCloneRangeTest) {
     ObjectStore::Transaction t;
     t.write(cid, hoid, 10, 5, small);
     cerr << "Creating object and write bl " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
@@ -3124,7 +3169,7 @@ TEST_P(StoreTest, SimpleCloneRangeTest) {
     ObjectStore::Transaction t;
     t.clone_range(cid, hoid, hoid2, 10, 5, 10);
     cerr << "Clone range object" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     r = store->read(cid, hoid2, 10, 5, newdata);
     ASSERT_EQ(r, 5);
@@ -3135,7 +3180,7 @@ TEST_P(StoreTest, SimpleCloneRangeTest) {
     t.truncate(cid, hoid, 1024*1024);
     t.clone_range(cid, hoid, hoid2, 0, 1024*1024, 0);
     cerr << "Clone range object" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     struct stat stat, stat2;
     r = store->stat(cid, hoid, &stat);
@@ -3149,21 +3194,21 @@ TEST_P(StoreTest, SimpleCloneRangeTest) {
     t.remove(cid, hoid2);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 
 TEST_P(StoreTest, SimpleObjectLongnameTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ghobject_t hoid(hobject_t(sobject_t("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaObjectaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1", CEPH_NOSNAP)));
@@ -3171,7 +3216,7 @@ TEST_P(StoreTest, SimpleObjectLongnameTest) {
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -3179,7 +3224,7 @@ TEST_P(StoreTest, SimpleObjectLongnameTest) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
@@ -3195,14 +3240,14 @@ ghobject_t generate_long_name(unsigned i)
 }
 
 TEST_P(StoreTest, LongnameSplitTest) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
   for (unsigned i = 0; i < 320; ++i) {
@@ -3210,7 +3255,7 @@ TEST_P(StoreTest, LongnameSplitTest) {
     ghobject_t hoid = generate_long_name(i);
     t.touch(cid, hoid);
     cerr << "Creating object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
 
@@ -3223,7 +3268,7 @@ TEST_P(StoreTest, LongnameSplitTest) {
     t.collection_move_rename(
       cid, test_obj,
       cid, test_obj_2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
 
@@ -3232,7 +3277,7 @@ TEST_P(StoreTest, LongnameSplitTest) {
     ghobject_t hoid = generate_long_name(i);
     t.remove(cid, hoid);
     cerr << "Removing object " << hoid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
   {
@@ -3240,24 +3285,24 @@ TEST_P(StoreTest, LongnameSplitTest) {
     t.remove(cid, test_obj_2);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(0, r);
   }
 
 }
 
 TEST_P(StoreTest, ManyObjectTest) {
-  ObjectStore::Sequencer osr("test");
   int NUM_OBJS = 2000;
   int r = 0;
   coll_t cid;
   string base = "";
   for (int i = 0; i < 100; ++i) base.append("aaaaa");
   set<ghobject_t> created;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   for (int i = 0; i < NUM_OBJS; ++i) {
@@ -3270,7 +3315,7 @@ TEST_P(StoreTest, ManyObjectTest) {
     ghobject_t hoid(hobject_t(sobject_t(string(buf) + base, CEPH_NOSNAP)));
     t.touch(cid, hoid);
     created.insert(hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -3281,7 +3326,7 @@ TEST_P(StoreTest, ManyObjectTest) {
     ASSERT_TRUE(!store->stat(cid, *i, &buf));
   }
 
-  osr.flush();
+  ch->flush();
 
   set<ghobject_t> listed, listed2;
   vector<ghobject_t> objects;
@@ -3345,14 +3390,14 @@ TEST_P(StoreTest, ManyObjectTest) {
        ++i) {
     ObjectStore::Transaction t;
     t.remove(cid, *i);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   cerr << "cleaning up" << std::endl;
   {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
@@ -3409,7 +3454,7 @@ public:
   ObjectGenerator *object_gen;
   gen_type *rng;
   ObjectStore *store;
-  ObjectStore::Sequencer *osr;
+  ObjectStore::CollectionHandle ch;
 
   Mutex lock;
   Cond cond;
@@ -3524,23 +3569,24 @@ public:
   SyntheticWorkloadState(ObjectStore *store,
                         ObjectGenerator *gen,
                         gen_type *rng,
-                        ObjectStore::Sequencer *osr,
                         coll_t cid,
                         unsigned max_size,
                         unsigned max_write,
                         unsigned alignment)
     : cid(cid), write_alignment(alignment), max_object_len(max_size),
       max_write_len(max_write), in_flight(0), object_gen(gen),
-      rng(rng), store(store), osr(osr), lock("State lock") {}
+      rng(rng), store(store),
+      lock("State lock") {}
 
   int init() {
     ObjectStore::Transaction t;
+    ch = store->create_new_collection(cid);
     t.create_collection(cid, 0);
-    return apply_transaction(store, osr, std::move(t));
+    return apply_transaction(store, ch, std::move(t));
   }
   void shutdown() {
     while (1) {
-      osr->flush();
+      ch->flush();
       vector<ghobject_t> objects;
       int r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
                                     10, &objects, 0);
@@ -3552,11 +3598,11 @@ public:
           p != objects.end(); ++p) {
        t.remove(cid, *p);
       }
-      apply_transaction(store, osr, std::move(t));
+      apply_transaction(store, ch, std::move(t));
     }
     ObjectStore::Transaction t;
     t.remove_collection(cid);
-    apply_transaction(store, osr, std::move(t));
+    apply_transaction(store, ch, std::move(t));
   }
   void statfs(store_statfs_t& stat) {
     store->statfs(&stat);
@@ -3579,7 +3625,7 @@ public:
   }
 
   void wait_for_done() {
-    osr->flush();
+    ch->flush();
     Mutex::Locker locker(lock);
     while (in_flight)
       cond.Wait(lock);
@@ -3667,7 +3713,7 @@ public:
     in_flight_objects.insert(new_obj);
     if (!contents.count(new_obj))
       contents[new_obj] = Object();
-    int status = store->queue_transaction(osr, std::move(t), new C_SyntheticOnReadable(this, new_obj));
+    int status = store->queue_transaction(ch, std::move(t), new C_SyntheticOnReadable(this, new_obj));
     return status;
   }
 
@@ -3699,7 +3745,7 @@ public:
     contents[new_obj].data = contents[old_obj].data;
     contents.erase(old_obj);
     int status = store->queue_transaction(
-      osr, std::move(t),
+      ch, std::move(t),
       new C_SyntheticOnStash(this, old_obj, new_obj));
     return status;
   }
@@ -3733,7 +3779,7 @@ public:
     contents[new_obj].data = contents[old_obj].data;
 
     int status = store->queue_transaction(
-      osr, std::move(t),
+      ch, std::move(t),
       new C_SyntheticOnClone(this, old_obj, new_obj));
     return status;
   }
@@ -3815,7 +3861,7 @@ public:
     }
 
     int status = store->queue_transaction(
-      osr, std::move(t), new C_SyntheticOnClone(this, old_obj, new_obj));
+      ch, std::move(t), new C_SyntheticOnClone(this, old_obj, new_obj));
     return status;
   }
 
@@ -3864,7 +3910,7 @@ public:
     ++in_flight;
     in_flight_objects.insert(new_obj);
     int status = store->queue_transaction(
-      osr, std::move(t), new C_SyntheticOnReadable(this, new_obj));
+      ch, std::move(t), new C_SyntheticOnReadable(this, new_obj));
     return status;
   }
 
@@ -3898,7 +3944,7 @@ public:
     }
 
     int status = store->queue_transaction(
-      osr, std::move(t), new C_SyntheticOnReadable(this, obj));
+      ch, std::move(t), new C_SyntheticOnReadable(this, obj));
     return status;
   }
 
@@ -3939,7 +3985,7 @@ public:
     ++in_flight;
     in_flight_objects.insert(new_obj);
     int status = store->queue_transaction(
-      osr, std::move(t), new C_SyntheticOnReadable(this, new_obj));
+      ch, std::move(t), new C_SyntheticOnReadable(this, new_obj));
     return status;
   }
 
@@ -4029,7 +4075,7 @@ public:
     ++in_flight;
     in_flight_objects.insert(obj);
     int status = store->queue_transaction(
-      osr, std::move(t), new C_SyntheticOnReadable(this, obj));
+      ch, std::move(t), new C_SyntheticOnReadable(this, obj));
     return status;
   }
 
@@ -4128,7 +4174,7 @@ public:
     ++in_flight;
     in_flight_objects.insert(obj);
     int status = store->queue_transaction(
-      osr, std::move(t), new C_SyntheticOnReadable(this, obj));
+      ch, std::move(t), new C_SyntheticOnReadable(this, obj));
     return status;
   }
 
@@ -4137,10 +4183,12 @@ public:
     EnterExit ee("fsck");
     while (in_flight)
       cond.Wait(lock);
+    ch.reset();
     store->umount();
     int r = store->fsck(deep);
     assert(r == 0 || r == -EOPNOTSUPP);
     store->mount();
+    ch = store->open_collection(cid);
   }
 
   void scan() {
@@ -4148,7 +4196,7 @@ public:
     EnterExit ee("scan");
     while (in_flight)
       cond.Wait(lock);
-    osr->flush();
+    ch->flush();
     vector<ghobject_t> objects;
     set<ghobject_t> objects_set, objects_set2;
     ghobject_t next, current;
@@ -4245,7 +4293,7 @@ public:
     available_objects.erase(to_remove);
     in_flight_objects.insert(to_remove);
     contents.erase(to_remove);
-    int status = store->queue_transaction(osr, std::move(t), new C_SyntheticOnReadable(this, to_remove));
+    int status = store->queue_transaction(ch, std::move(t), new C_SyntheticOnReadable(this, to_remove));
     return status;
   }
 
@@ -4263,7 +4311,6 @@ void doSyntheticTest(boost::scoped_ptr<ObjectStore>& store,
                     int num_ops,
                     uint64_t max_obj, uint64_t max_wr, uint64_t align)
 {
-  ObjectStore::Sequencer osr("test");
   MixedGenerator gen(555);
   gen_type rng(time(NULL));
   coll_t cid(spg_t(pg_t(0,555), shard_id_t::NO_SHARD));
@@ -4272,7 +4319,7 @@ void doSyntheticTest(boost::scoped_ptr<ObjectStore>& store,
   g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "false");
   g_ceph_context->_conf->apply_changes(NULL);
 
-  SyntheticWorkloadState test_obj(store.get(), &gen, &rng, &osr, cid,
+  SyntheticWorkloadState test_obj(store.get(), &gen, &rng, cid,
                                  max_obj, max_wr, align);
   test_obj.init();
   for (int i = 0; i < num_ops/10; ++i) {
@@ -4352,14 +4399,14 @@ TEST_P(StoreTestSpecificAUSize, ZipperPatternSharded) {
   StartDeferred(4096);
 
   int r;
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist bl;
@@ -4370,13 +4417,13 @@ TEST_P(StoreTestSpecificAUSize, ZipperPatternSharded) {
   for (int i=0; i<1000; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, a, i*2*len, len, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   for (int i=0; i<1000; ++i) {
     ObjectStore::Transaction t;
     t.write(cid, a, i*2*len + 1, len, bl, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -4384,7 +4431,7 @@ TEST_P(StoreTestSpecificAUSize, ZipperPatternSharded) {
     t.remove(cid, a);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
@@ -4498,12 +4545,11 @@ TEST_P(StoreTestSpecificAUSize, SyntheticMatrixPreferDeferred) {
 }
 
 TEST_P(StoreTest, AttrSynthetic) {
-  ObjectStore::Sequencer osr("test");
   MixedGenerator gen(447);
   gen_type rng(time(NULL));
   coll_t cid(spg_t(pg_t(0,447),shard_id_t::NO_SHARD));
 
-  SyntheticWorkloadState test_obj(store.get(), &gen, &rng, &osr, cid, 40*1024, 4*1024, 0);
+  SyntheticWorkloadState test_obj(store.get(), &gen, &rng, cid, 40*1024, 4*1024, 0);
   test_obj.init();
   for (int i = 0; i < 500; ++i) {
     if (!(i % 10)) cerr << "seeding object " << i << std::endl;
@@ -4539,14 +4585,14 @@ TEST_P(StoreTest, AttrSynthetic) {
 }
 
 TEST_P(StoreTest, HashCollisionTest) {
-  ObjectStore::Sequencer osr("test");
   int64_t poolid = 11;
   coll_t cid(spg_t(pg_t(0,poolid),shard_id_t::NO_SHARD));
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   string base = "";
@@ -4565,14 +4611,14 @@ TEST_P(StoreTest, HashCollisionTest) {
     {
       ObjectStore::Transaction t;
       t.touch(cid, hoid);
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     created.insert(hoid);
   }
   }
   vector<ghobject_t> objects;
-  osr.flush();
+  ch->flush();
   r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(), INT_MAX, &objects, 0);
   ASSERT_EQ(r, 0);
   set<ghobject_t> listed(objects.begin(), objects.end());
@@ -4613,24 +4659,24 @@ TEST_P(StoreTest, HashCollisionTest) {
        ++i) {
     ObjectStore::Transaction t;
     t.remove(cid, *i);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ObjectStore::Transaction t;
   t.remove_collection(cid);
-  r = apply_transaction(store, &osr, std::move(t));
+  r = apply_transaction(store, ch, std::move(t));
   ASSERT_EQ(r, 0);
 }
 
 TEST_P(StoreTest, ScrubTest) {
-  ObjectStore::Sequencer osr("test");
   int64_t poolid = 111;
   coll_t cid(spg_t(pg_t(0, poolid),shard_id_t(1)));
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   string base = "aaaaa";
@@ -4647,7 +4693,7 @@ TEST_P(StoreTest, ScrubTest) {
     {
       ObjectStore::Transaction t;
       t.touch(cid, hoid);
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     created.insert(hoid);
@@ -4663,14 +4709,14 @@ TEST_P(StoreTest, ScrubTest) {
     t.touch(cid, hoid1);
     t.touch(cid, hoid2);
     t.touch(cid, hoid3);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     created.insert(hoid1);
     created.insert(hoid2);
     created.insert(hoid3);
     ASSERT_EQ(r, 0);
   }
 
-  osr.flush();
+  ch->flush();
   vector<ghobject_t> objects;
   r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
                             INT_MAX, &objects, 0);
@@ -4712,25 +4758,25 @@ TEST_P(StoreTest, ScrubTest) {
        ++i) {
     ObjectStore::Transaction t;
     t.remove(cid, *i);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ObjectStore::Transaction t;
   t.remove_collection(cid);
-  r = apply_transaction(store, &osr, std::move(t));
+  r = apply_transaction(store, ch, std::move(t));
   ASSERT_EQ(r, 0);
 }
 
 
 TEST_P(StoreTest, OMapTest) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t("tesomap", "", CEPH_NOSNAP, 0, 0, ""));
+  auto ch = store->create_new_collection(cid);
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -4741,7 +4787,7 @@ TEST_P(StoreTest, OMapTest) {
     t.omap_clear(cid, hoid);
     map<string, bufferlist> start_set;
     t.omap_setkeys(cid, hoid, start_set);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -4777,7 +4823,7 @@ TEST_P(StoreTest, OMapTest) {
     to_add.insert(pair<string, bufferlist>("key-" + string(buf), bl));
     attrs.insert(pair<string, bufferlist>("key-" + string(buf), bl));
     t.omap_setkeys(cid, hoid, to_add);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -4808,7 +4854,7 @@ TEST_P(StoreTest, OMapTest) {
     set<string> keys_to_remove;
     keys_to_remove.insert(to_remove);
     t.omap_rmkeys(cid, hoid, keys_to_remove);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     attrs.erase(to_remove);
@@ -4821,7 +4867,7 @@ TEST_P(StoreTest, OMapTest) {
     bl1.append("omap_header");
     ObjectStore::Transaction t;
     t.omap_setheader(cid, hoid, bl1);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
     t = ObjectStore::Transaction();
  
@@ -4830,7 +4876,7 @@ TEST_P(StoreTest, OMapTest) {
     map<string, bufferlist> to_add;
     to_add.insert(pair<string, bufferlist>("key", bl2));
     t.omap_setkeys(cid, hoid, to_add);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bufferlist bl3;
@@ -4860,13 +4906,13 @@ TEST_P(StoreTest, OMapTest) {
       t.touch(cid, hoid);
       t.omap_setheader(cid, hoid, h);
       t.omap_setkeys(cid, hoid, to_set);
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     {
       ObjectStore::Transaction t;
       t.omap_rmkeyrange(cid, hoid, "3", "7");
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     {
@@ -4885,7 +4931,7 @@ TEST_P(StoreTest, OMapTest) {
     {
       ObjectStore::Transaction t;
       t.omap_clear(cid, hoid);
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     {
@@ -4900,20 +4946,20 @@ TEST_P(StoreTest, OMapTest) {
   ObjectStore::Transaction t;
   t.remove(cid, hoid);
   t.remove_collection(cid);
-  r = apply_transaction(store, &osr, std::move(t));
+  r = apply_transaction(store, ch, std::move(t));
   ASSERT_EQ(r, 0);
 }
 
 TEST_P(StoreTest, OMapIterator) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t("tesomap", "", CEPH_NOSNAP, 0, 0, ""));
   int count = 0;
+  auto ch = store->create_new_collection(cid);
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -4924,7 +4970,7 @@ TEST_P(StoreTest, OMapIterator) {
     t.omap_clear(cid, hoid);
     map<string, bufferlist> start_set;
     t.omap_setkeys(cid, hoid, start_set);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ObjectMap::ObjectMapIterator iter;
@@ -4968,7 +5014,7 @@ TEST_P(StoreTest, OMapIterator) {
     attrs.insert(pair<string, bufferlist>("key-" + string(buf), bl));
     ObjectStore::Transaction t;
     t.omap_setkeys(cid, hoid, to_add);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -4995,13 +5041,12 @@ TEST_P(StoreTest, OMapIterator) {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, XattrTest) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t("tesomap", "", CEPH_NOSNAP, 0, 0, ""));
   bufferlist big;
@@ -5013,11 +5058,12 @@ TEST_P(StoreTest, XattrTest) {
     small.append('\0');
   }
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -5036,7 +5082,7 @@ TEST_P(StoreTest, XattrTest) {
     attrs["attr4"] = big;
     t.setattr(cid, hoid, "attr3", big);
     attrs["attr3"] = big;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -5055,7 +5101,7 @@ TEST_P(StoreTest, XattrTest) {
     ObjectStore::Transaction t;
     t.rmattr(cid, hoid, "attr2");
     attrs.erase("attr2");
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -5083,7 +5129,7 @@ TEST_P(StoreTest, XattrTest) {
   ObjectStore::Transaction t;
   t.remove(cid, hoid);
   t.remove_collection(cid);
-  r = apply_transaction(store, &osr, std::move(t));
+  r = apply_transaction(store, ch, std::move(t));
   ASSERT_EQ(r, 0);
 }
 
@@ -5093,14 +5139,15 @@ void colsplittest(
   unsigned common_suffix_size,
   bool clones
   ) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid(spg_t(pg_t(0,52),shard_id_t::NO_SHARD));
   coll_t tid(spg_t(pg_t(1<<common_suffix_size,52),shard_id_t::NO_SHARD));
+  auto ch = store->create_new_collection(cid);
+  auto tch = store->create_new_collection(tid);
   int r = 0;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, common_suffix_size);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   bufferlist small;
@@ -5129,23 +5176,23 @@ void colsplittest(
        t.clone(cid, a, b);
       }
       if (i % 100) {
-       r = apply_transaction(store, &osr, std::move(t));
+       r = apply_transaction(store, ch, std::move(t));
        ASSERT_EQ(r, 0);
        t = ObjectStore::Transaction();
       }
     }
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.create_collection(tid, common_suffix_size + 1);
     t.split_collection(cid, common_suffix_size+1, 1<<common_suffix_size, tid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, tch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
-  osr.flush();
+  ch->flush();
   ObjectStore::Transaction t;
   vector<ghobject_t> objects;
   r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
@@ -5160,13 +5207,13 @@ void colsplittest(
     t.remove(cid, *i);
     if (++size > 100) {
       size = 0;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
       t = ObjectStore::Transaction();
     }
   }
 
-  osr.flush();
+  ch->flush();
   objects.clear();
   r = store->collection_list(tid, ghobject_t(), ghobject_t::get_max(),
                             INT_MAX, &objects, 0);
@@ -5179,7 +5226,7 @@ void colsplittest(
     t.remove(tid, *i);
     if (++size > 100) {
       size = 0;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, tch, std::move(t));
       ASSERT_EQ(r, 0);
       t = ObjectStore::Transaction();
     }
@@ -5187,7 +5234,7 @@ void colsplittest(
 
   t.remove_collection(cid);
   t.remove_collection(tid);
-  r = apply_transaction(store, &osr, std::move(t));
+  r = apply_transaction(store, tch, std::move(t));
   ASSERT_EQ(r, 0);
 }
 
@@ -5218,13 +5265,13 @@ TEST_P(StoreTest, ColSplitTest3) {
  * stops at the common prefix subdir.  See bug
  * #5273 */
 TEST_P(StoreTest, TwoHash) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   int r;
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   std::cout << "Making objects" << std::endl;
@@ -5238,7 +5285,7 @@ TEST_P(StoreTest, TwoHash) {
     }
     o.hobj.set_hash((i << 16) | 0xB1);
     t.touch(cid, o);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   std::cout << "Removing half" << std::endl;
@@ -5248,7 +5295,7 @@ TEST_P(StoreTest, TwoHash) {
     o.hobj.pool = -1;
     o.hobj.set_hash((i << 16) | 0xA1);
     t.remove(cid, o);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   std::cout << "Checking" << std::endl;
@@ -5276,29 +5323,29 @@ TEST_P(StoreTest, TwoHash) {
     t.remove(cid, o);
     o.hobj.set_hash((i << 16) | 0xB1);
     t.remove(cid, o);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ObjectStore::Transaction t;
   t.remove_collection(cid);
-  r = apply_transaction(store, &osr, std::move(t));
+  r = apply_transaction(store, ch, std::move(t));
   ASSERT_EQ(r, 0);
 }
 
 TEST_P(StoreTest, Rename) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid(spg_t(pg_t(0, 2122),shard_id_t::NO_SHARD));
   ghobject_t srcoid(hobject_t("src_oid", "", CEPH_NOSNAP, 0, 0, ""));
   ghobject_t dstoid(hobject_t("dest_oid", "", CEPH_NOSNAP, 0, 0, ""));
   bufferlist a, b;
   a.append("foo");
   b.append("bar");
+  auto ch = store->create_new_collection(cid);
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.write(cid, srcoid, 0, a.length(), a);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, srcoid));
@@ -5307,7 +5354,7 @@ TEST_P(StoreTest, Rename) {
     t.collection_move_rename(cid, srcoid, cid, dstoid);
     t.write(cid, srcoid, 0, b.length(), b);
     t.setattr(cid, srcoid, "attr", b);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, srcoid));
@@ -5323,7 +5370,7 @@ TEST_P(StoreTest, Rename) {
     ObjectStore::Transaction t;
     t.remove(cid, dstoid);
     t.collection_move_rename(cid, srcoid, cid, dstoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, dstoid));
@@ -5337,22 +5384,22 @@ TEST_P(StoreTest, Rename) {
     ObjectStore::Transaction t;
     t.remove(cid, dstoid);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, MoveRename) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid(spg_t(pg_t(0, 212),shard_id_t::NO_SHARD));
   ghobject_t temp_oid(hobject_t("tmp_oid", "", CEPH_NOSNAP, 0, 0, ""));
   ghobject_t oid(hobject_t("dest_oid", "", CEPH_NOSNAP, 0, 0, ""));
+  auto ch = store->create_new_collection(cid);
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, oid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, oid));
@@ -5367,7 +5414,7 @@ TEST_P(StoreTest, MoveRename) {
     t.write(cid, temp_oid, 0, data.length(), data);
     t.setattr(cid, temp_oid, "attr", attr);
     t.omap_setkeys(cid, temp_oid, omap);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, temp_oid));
@@ -5375,7 +5422,7 @@ TEST_P(StoreTest, MoveRename) {
     ObjectStore::Transaction t;
     t.remove(cid, oid);
     t.collection_move_rename(cid, temp_oid, cid, oid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, oid));
@@ -5402,13 +5449,12 @@ TEST_P(StoreTest, MoveRename) {
     ObjectStore::Transaction t;
     t.remove(cid, oid);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, BigRGWObjectName) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid(spg_t(pg_t(0,12),shard_id_t::NO_SHARD));
   ghobject_t oid(
     hobject_t(
@@ -5425,6 +5471,8 @@ TEST_P(StoreTest, BigRGWObjectName) {
   ghobject_t oidhead(oid);
   oidhead.generation = ghobject_t::NO_GEN;
 
+  auto ch = store->create_new_collection(cid);
+
   int r;
   {
     ObjectStore::Transaction t;
@@ -5433,18 +5481,18 @@ TEST_P(StoreTest, BigRGWObjectName) {
     t.collection_move_rename(cid, oidhead, cid, oid);
     t.touch(cid, oidhead);
     t.collection_move_rename(cid, oidhead, cid, oid2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
   {
     ObjectStore::Transaction t;
     t.remove(cid, oid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
-  osr.flush();
+  ch->flush();
 
   {
     vector<ghobject_t> objects;
@@ -5461,78 +5509,78 @@ TEST_P(StoreTest, BigRGWObjectName) {
     ObjectStore::Transaction t;
     t.remove(cid, oid2);
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
   }
 }
 
 TEST_P(StoreTest, SetAllocHint) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, 0, ""));
+  auto ch = store->create_new_collection(cid);
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     t.touch(cid, hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*4, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*4, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.remove_collection(cid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
 
 TEST_P(StoreTest, TryMoveRename) {
-  ObjectStore::Sequencer osr("test");
   coll_t cid;
   ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
   ghobject_t hoid2(hobject_t("test_hint2", "", CEPH_NOSNAP, 0, -1, ""));
+  auto ch = store->create_new_collection(cid);
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.try_rename(cid, hoid, hoid2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.touch(cid, hoid);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
     ObjectStore::Transaction t;
     t.try_rename(cid, hoid, hoid2);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   struct stat st;
@@ -5547,7 +5595,6 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
   g_conf->set_val("bluestore_csum_type", "crc32c");
   g_conf->apply_changes(NULL);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
@@ -5556,11 +5603,12 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     r = store->read(cid, hoid, 0, 5, in);
     ASSERT_EQ(-ENOENT, r);
   }
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -5574,7 +5622,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*8, 0);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "Remove then create" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     g_conf->set_val("bluestore_csum_type", "none");
@@ -5598,7 +5646,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*8, 0);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "Remove then create" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     g_conf->set_val("bluestore_csum_type", "crc32c");
@@ -5620,7 +5668,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     t.remove(cid, hoid);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "Remove then create" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     g_conf->set_val("bluestore_csum_type", "none");
@@ -5629,7 +5677,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     ObjectStore::Transaction t2;
     t2.write(cid, hoid, block_size*2, bl.length(), bl);
     cerr << "Append 'unprotected'" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t2));
+    r = apply_transaction(store, ch, std::move(t2));
     ASSERT_EQ(r, 0);
 
     bufferlist in;
@@ -5665,7 +5713,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*8, 0);
     t.write(cid, hoid, 0, bl.length(), bl);
     cerr << "Remove then create" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     g_conf->set_val("bluestore_csum_type", "none");
@@ -5677,7 +5725,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     t2.write(cid, hoid, 0, bl.length(), bl);
     t2.write(cid, hoid, block_size0, bl.length(), bl);
     cerr << "Overwrite with unprotected data" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t2));
+    r = apply_transaction(store, ch, std::move(t2));
     ASSERT_EQ(r, 0);
 
     orig = bl;
@@ -5701,7 +5749,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     bl.append(std::string(block_size2, 'c'));
     t3.write(cid, hoid, block_size0, bl.length(), bl);
     cerr << "Overwrite with protected data" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t3));
+    r = apply_transaction(store, ch, std::move(t3));
     ASSERT_EQ(r, 0);
 
     in.clear();
@@ -5717,7 +5765,7 @@ TEST_P(StoreTest, BluestoreOnOffCSumTest) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 }
@@ -5766,7 +5814,6 @@ void doMany4KWritesTest(boost::scoped_ptr<ObjectStore>& store,
                         unsigned write_alignment,
                         store_statfs_t* res_stat)
 {
-  ObjectStore::Sequencer osr("test");
   MixedGenerator gen(555);
   gen_type rng(time(NULL));
   coll_t cid(spg_t(pg_t(0,555), shard_id_t::NO_SHARD));
@@ -5774,7 +5821,6 @@ void doMany4KWritesTest(boost::scoped_ptr<ObjectStore>& store,
   SyntheticWorkloadState test_obj(store.get(),
                                   &gen,
                                   &rng,
-                                  &osr,
                                   cid,
                                   max_object_size,
                                   max_write_size,
@@ -5868,7 +5914,6 @@ TEST_P(StoreTestSpecificAUSize, OnodeSizeTracking) {
   g_conf->set_val("bluestore_cache_size_ssd", "400000000");
   g_conf->apply_changes(NULL);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
@@ -5878,10 +5923,11 @@ TEST_P(StoreTestSpecificAUSize, OnodeSizeTracking) {
   get_mempool_stats(&total_bytes, &total_onodes);
   ASSERT_EQ(total_onodes, 0u);
 
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -5890,7 +5936,7 @@ TEST_P(StoreTestSpecificAUSize, OnodeSizeTracking) {
     
     bl.append(std::string(obj_size, 'a'));
     t.write(cid, hoid, 0, bl.length(), bl);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   get_mempool_stats(&total_bytes, &total_onodes);
@@ -5900,7 +5946,7 @@ TEST_P(StoreTestSpecificAUSize, OnodeSizeTracking) {
   {
     ObjectStore::Transaction t;
     t.truncate(cid, hoid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
  
@@ -5910,7 +5956,7 @@ TEST_P(StoreTestSpecificAUSize, OnodeSizeTracking) {
     for( size_t j = 0; j < obj_size; j+= bl.length()) {
       ObjectStore::Transaction t;
       t.write(cid, hoid, j, bl.length(), bl);
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
     get_mempool_stats(&total_bytes2, &total_onodes);
@@ -5950,7 +5996,7 @@ TEST_P(StoreTestSpecificAUSize, OnodeSizeTracking) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_ceph_context->_conf->set_val("bluestore_cache_size_hdd", "4000000");
@@ -5970,17 +6016,17 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
   g_conf->set_val("bluestore_max_blob_size", "65536");
   g_conf->apply_changes(NULL);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
 
   const PerfCounters* logger = store->get_perf_counters();
 
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -5989,7 +6035,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
 
     bl.append(std::string(block_size * 2, 'a'));
     t.write(cid, hoid, 0, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -5999,7 +6045,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
 
     bl.append(std::string(block_size, 'b'));
     t.write(cid, hoid, 0, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6009,7 +6055,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
 
     bl.append(std::string(block_size * 2, 'c'));
     t.write(cid, hoid, block_size * 2, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6019,7 +6065,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
 
     bl.append(std::string(block_size * 2, 'd'));
     t.write(cid, hoid, block_size * 5, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6044,7 +6090,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
 
     // Currently we are unable to reuse blob when overwriting in a single step
     t.write(cid, hoid, block_size * 6, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6068,7 +6114,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
     bl.append(std::string(block_size, 'f'));
 
     t.write(cid, hoid, block_size * 4, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6128,7 +6174,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_conf->set_val("bluestore_max_blob_size", "0");
@@ -6146,16 +6192,17 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
 
   g_conf->apply_changes(NULL);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
 
+  auto ch = store->create_new_collection(cid);
+
   const PerfCounters* logger = store->get_perf_counters();
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6165,7 +6212,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
     bl.append(std::string(block_size * 2, 'a'));
     t.write(cid, hoid, block_size * 10, bl.length(), bl, 
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6176,7 +6223,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
     bl.append(std::string(block_size, 'b'));
     t.write(cid, hoid, block_size * 9, bl.length(), bl,
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6203,7 +6250,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
     bl.append(std::string(block_size, 'c'));
     t.write(cid, hoid, block_size * 7, bl.length(), bl,
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6230,7 +6277,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
     bl.append(std::string(block_size, 'd'));
     t.write(cid, hoid, block_size * 13, bl.length(), bl,
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6259,7 +6306,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
     t.write(cid, hoid, block_size * 19, bl.length(), bl,
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6287,7 +6334,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
     t.write(cid, hoid, block_size * 18, bl.length(), bl,
             CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6311,7 +6358,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_conf->set_val("bluestore_max_blob_size", "0");
@@ -6327,17 +6374,17 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnSmallOverwrite) {
   g_conf->set_val("bluestore_max_blob_size", "65536");
   g_conf->apply_changes(NULL);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
 
   const PerfCounters* logger = store->get_perf_counters();
+  auto ch = store->create_new_collection(cid);
 
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6348,7 +6395,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnSmallOverwrite) {
     t.write(cid, hoid, 0, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
     t.write(cid, hoid, block_size * 2, bl.length(), bl,
       CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6359,7 +6406,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnSmallOverwrite) {
     bl.append(std::string(3, 'b'));
     t.write(cid, hoid, block_size + 1, bl.length(), bl,
       CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6385,7 +6432,7 @@ TEST_P(StoreTestSpecificAUSize, BlobReuseOnSmallOverwrite) {
     t.remove(cid, hoid);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_conf->set_val("bluestore_max_blob_size", "0");
@@ -6409,15 +6456,15 @@ TEST_P(StoreTestSpecificAUSize, SmallWriteOnShardedExtents) {
 
   g_conf->apply_changes(NULL);
 
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   ghobject_t hoid1(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  auto ch = store->create_new_collection(cid);
 
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   {
@@ -6428,18 +6475,20 @@ TEST_P(StoreTestSpecificAUSize, SmallWriteOnShardedExtents) {
     bl.append(std::string(0x80000, 'a'));
     t.write(cid, hoid1, 0, bl.length(), bl, 0);
     t.zero(cid, hoid1, 0x719e0, 0x75b0 );
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
     bl2.append(std::string(0x70000, 'b'));
     t.write(cid, hoid1, 0, bl2.length(), bl2, 0);
     t.zero(cid, hoid1, 0, 0x50000);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
 
   }
+  ch.reset();
   store->umount();
   store->mount();
+  ch = store->open_collection(cid);
 
   {
     // do a write to zero space in between some extents sharing the same blob
@@ -6449,7 +6498,7 @@ TEST_P(StoreTestSpecificAUSize, SmallWriteOnShardedExtents) {
     bl.append(std::string(0x6520, 'c'));
     t.write(cid, hoid1, 0x71c00, bl.length(), bl, 0);
 
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -6474,7 +6523,7 @@ TEST_P(StoreTestSpecificAUSize, SmallWriteOnShardedExtents) {
     t.remove(cid, hoid1);
     t.remove_collection(cid);
     cerr << "Cleaning" << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   g_conf->set_val("bluestore_max_target_blob", "524288");
@@ -6487,7 +6536,6 @@ TEST_P(StoreTest, KVDBHistogramTest) {
   if (string(GetParam()) != "bluestore")
     return;
 
-  ObjectStore::Sequencer osr("test");
   int NUM_OBJS = 200;
   int r = 0;
   coll_t cid;
@@ -6496,10 +6544,11 @@ TEST_P(StoreTest, KVDBHistogramTest) {
   bufferptr ap(0x1000);
   memset(ap.c_str(), 'a', 0x1000);
   a.append(ap);
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   for (int i = 0; i < NUM_OBJS; ++i) {
@@ -6508,7 +6557,7 @@ TEST_P(StoreTest, KVDBHistogramTest) {
     snprintf(buf, sizeof(buf), "%d", i);
     ghobject_t hoid(hobject_t(sobject_t(base + string(buf), CEPH_NOSNAP)));
     t.write(cid, hoid, 0, 0x1000, a);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -6532,7 +6581,6 @@ TEST_P(StoreTest, KVDBStatsTest) {
   r = store->mount(); //to force rocksdb stats
   ASSERT_EQ(r, 0);
 
-  ObjectStore::Sequencer osr("test");
   int NUM_OBJS = 200;
   coll_t cid;
   string base("testobj.");
@@ -6540,10 +6588,11 @@ TEST_P(StoreTest, KVDBStatsTest) {
   bufferptr ap(0x1000);
   memset(ap.c_str(), 'a', 0x1000);
   a.append(ap);
+  auto ch = store->create_new_collection(cid);
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
   for (int i = 0; i < NUM_OBJS; ++i) {
@@ -6552,7 +6601,7 @@ TEST_P(StoreTest, KVDBStatsTest) {
     snprintf(buf, sizeof(buf), "%d", i);
     ghobject_t hoid(hobject_t(sobject_t(base + string(buf), CEPH_NOSNAP)));
     t.write(cid, hoid, 0, 0x1000, a);
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -6568,7 +6617,6 @@ TEST_P(StoreTest, KVDBStatsTest) {
 
 #if defined(WITH_BLUESTORE)
 TEST_P(StoreTestSpecificAUSize, garbageCollection) {
-  ObjectStore::Sequencer osr("test");
   int r;
   coll_t cid;
   int buf_len = 256 * 1024;
@@ -6587,7 +6635,7 @@ TEST_P(StoreTestSpecificAUSize, garbageCollection) {
       } else {\
         t.write(cid, hoid, offset, bl.length(), bl);\
       }\
-      r = apply_transaction(store, &osr, std::move(t));\
+      r = apply_transaction(store, ch, std::move(t));\
       ASSERT_EQ(r, 0);\
   }
 
@@ -6598,6 +6646,8 @@ TEST_P(StoreTestSpecificAUSize, garbageCollection) {
   g_conf->set_val("bluestore_compression_mode", "force");
   g_conf->apply_changes(NULL);
 
+  auto ch = store->create_new_collection(cid);
+
   ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
   {
     bufferlist in;
@@ -6608,7 +6658,7 @@ TEST_P(StoreTestSpecificAUSize, garbageCollection) {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
     cerr << "Creating collection " << cid << std::endl;
-    r = apply_transaction(store, &osr, std::move(t));
+    r = apply_transaction(store, ch, std::move(t));
     ASSERT_EQ(r, 0);
   }
 
@@ -6623,7 +6673,7 @@ TEST_P(StoreTestSpecificAUSize, garbageCollection) {
       ObjectStore::Transaction t;
       t.touch(cid, hoid);
       cerr << "Creating object " << hoid << std::endl;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
 
       exists = store->exists(cid, hoid);
@@ -6722,7 +6772,7 @@ TEST_P(StoreTestSpecificAUSize, garbageCollection) {
       ObjectStore::Transaction t;
       t.remove(cid, hoid);
       cerr << "Cleaning" << std::endl;
-      r = apply_transaction(store, &osr, std::move(t));
+      r = apply_transaction(store, ch, std::move(t));
       ASSERT_EQ(r, 0);
     }
   }
@@ -6784,8 +6834,9 @@ int main(int argc, char **argv) {
   g_ceph_context->_conf->set_val("filestore_op_thread_timeout", "1000");
   g_ceph_context->_conf->set_val("filestore_op_thread_suicide_timeout", "10000");
   //g_ceph_context->_conf->set_val("filestore_fiemap", "true");
-  g_ceph_context->_conf->set_val("bluestore_fsck_on_mount", "true");
-  g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "true");
+  g_ceph_context->_conf->set_val("bluestore_fsck_on_mkfs", "false");
+  g_ceph_context->_conf->set_val("bluestore_fsck_on_mount", "false");
+  g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "false");
   g_ceph_context->_conf->set_val("bluestore_debug_misc", "true");
   g_ceph_context->_conf->set_val("bluestore_debug_small_allocations", "4");
   g_ceph_context->_conf->set_val("bluestore_debug_freelist", "true");
index e90943a444882b0bc5c5530409c7eff235cc4242..adedc0330e0f9967e89c6a81915352be39930263 100644 (file)
@@ -10,6 +10,7 @@ class StoreTestFixture : virtual public ::testing::Test {
 
 public:
   boost::scoped_ptr<ObjectStore> store;
+  ObjectStore::CollectionHandle ch;
 
   StoreTestFixture(const std::string& type)
     : type(type), data_dir(type + ".test_temp_dir")
index 6df2cedb0dec930f8505ae0721b97f3327f0f3db..33a00c4338b4e7513ea0a787947c9c485f32b33a 100644 (file)
@@ -69,18 +69,20 @@ int main(int argc, char **argv) {
   boost::scoped_ptr<ObjectStore> store(new FileStore(cct.get(), store_path,
                                                     store_dev));
 
-  ObjectStore::Sequencer osr(__func__);
   coll_t coll(spg_t(pg_t(0,12),shard_id_t::NO_SHARD));
+  ObjectStore::CollectionHandle ch;
 
   if (start_new) {
     std::cerr << "mkfs" << std::endl;
     assert(!store->mkfs());
     ObjectStore::Transaction t;
     assert(!store->mount());
+    ch = store->create_new_collection(coll);
     t.create_collection(coll, 0);
-    store->apply_transaction(&osr, std::move(t));
+    store->apply_transaction(ch, std::move(t));
   } else {
     assert(!store->mount());
+    ch = store->open_collection(coll);
   }
 
   FileStoreTracker tracker(store.get(), db.get());
index 08df9a5771cf5a6b4172df81e9c238183cc2c65a..451fa51f8efb127c80b7ea108825a46500a8c961 100644 (file)
@@ -114,7 +114,8 @@ int run_get_last_op(std::string& filestore_path, std::string& journal_path)
   coll_t txn_coll;
   ghobject_t txn_object(hobject_t(sobject_t("txn", CEPH_NOSNAP)));
   bufferlist bl;
-  store->read(txn_coll, txn_object, 0, 100, bl);
+  auto ch = store->open_collection(txn_coll);
+  store->read(ch, txn_object, 0, 100, bl);
   int32_t txn = 0;
   if (bl.length()) {
     bufferlist::iterator p = bl.begin();
index aa5374790ca23fd2836d437245840ba2e78ea107..9540f230b69159db330f09f1673362f4073cda13 100644 (file)
@@ -44,13 +44,18 @@ public:
       return;
     }
     ObjectStore::Transaction t;
+    ch = store->create_new_collection(cid);
     t.create_collection(cid, 4);
-    unsigned r = store->apply_transaction(nullptr, std::move(t));
+    unsigned r = store->apply_transaction(ch, std::move(t));
     if (r != 0) {
       derr << "failed to create collection with " << cpp_strerror(r) << dendl;
     }
     ASSERT_EQ(0U, r);
   }
+  void TearDown() override {
+    ch.reset();
+    StoreTestFixture::TearDown();
+  }
 };
 
 // src 11[11 11 11 11]11
@@ -72,7 +77,7 @@ TEST_F(MemStoreClone, CloneRangeAllocated)
   t.write(cid, src, 0, 12, srcbl);
   t.write(cid, dst, 0, 12, dstbl);
   t.clone_range(cid, src, dst, 2, 8, 2);
-  ASSERT_EQ(0u, store->apply_transaction(nullptr, std::move(t)));
+  ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t)));
   ASSERT_EQ(12, store->read(cid, dst, 0, 12, result));
   ASSERT_EQ(expected, result);
 }
@@ -96,7 +101,7 @@ TEST_F(MemStoreClone, CloneRangeHole)
   t.write(cid, src, 12, 4, srcbl);
   t.write(cid, dst, 0, 12, dstbl);
   t.clone_range(cid, src, dst, 2, 8, 2);
-  ASSERT_EQ(0u, store->apply_transaction(nullptr, std::move(t)));
+  ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t)));
   ASSERT_EQ(12, store->read(cid, dst, 0, 12, result));
   ASSERT_EQ(expected, result);
 }
@@ -120,7 +125,7 @@ TEST_F(MemStoreClone, CloneRangeHoleStart)
   t.write(cid, src, 8, 4, srcbl);
   t.write(cid, dst, 0, 12, dstbl);
   t.clone_range(cid, src, dst, 2, 8, 2);
-  ASSERT_EQ(0u, store->apply_transaction(nullptr, std::move(t)));
+  ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t)));
   ASSERT_EQ(12, store->read(cid, dst, 0, 12, result));
   ASSERT_EQ(expected, result);
 }
@@ -145,7 +150,7 @@ TEST_F(MemStoreClone, CloneRangeHoleMiddle)
   t.write(cid, src, 8, 4, srcbl);
   t.write(cid, dst, 0, 12, dstbl);
   t.clone_range(cid, src, dst, 2, 8, 2);
-  ASSERT_EQ(0u, store->apply_transaction(nullptr, std::move(t)));
+  ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t)));
   ASSERT_EQ(12, store->read(cid, dst, 0, 12, result));
   ASSERT_EQ(expected, result);
 }
@@ -170,7 +175,7 @@ TEST_F(MemStoreClone, CloneRangeHoleEnd)
   t.write(cid, src, 12, 4, srcbl);
   t.write(cid, dst, 0, 12, dstbl);
   t.clone_range(cid, src, dst, 2, 8, 2);
-  ASSERT_EQ(0u, store->apply_transaction(nullptr, std::move(t)));
+  ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t)));
   ASSERT_EQ(12, store->read(cid, dst, 0, 12, result));
   ASSERT_EQ(expected, result);
 }
index 60c5d597e24528fa2c0bf63d8a24f29cde92ccab..2524a3c41fdc3fbe3c286dd2f6ea3f3c188bb429 100644 (file)
@@ -107,7 +107,8 @@ void osbench_worker(ObjectStore *os, const Config &cfg,
   assert(starting_offset < cfg.size);
   assert(starting_offset % cfg.block_size == 0);
 
-  ObjectStore::Sequencer sequencer("osbench");
+  ObjectStore::CollectionHandle ch = os->open_collection(cid);
+  assert(ch);
 
   for (int i = 0; i < cfg.repeats; ++i) {
     uint64_t offset = starting_offset;
@@ -135,16 +136,13 @@ void osbench_worker(ObjectStore *os, const Config &cfg,
     std::condition_variable cond;
     bool done = false;
 
-    os->queue_transactions(&sequencer, tls, nullptr,
-                           new C_NotifyCond(&mutex, &cond, &done));
+    tls.back().register_on_commit(new C_NotifyCond(&mutex, &cond, &done));
+    os->queue_transactions(ch, tls);
 
     std::unique_lock<std::mutex> lock(mutex);
     cond.wait(lock, [&done](){ return done; });
     lock.unlock();
-
-
   }
-  sequencer.flush();
 }
 
 int main(int argc, const char *argv[])
@@ -257,11 +255,11 @@ int main(int argc, const char *argv[])
   // create a collection
   spg_t pg;
   const coll_t cid(pg);
+  ObjectStore::CollectionHandle ch = os->create_new_collection(cid);
   {
-    ObjectStore::Sequencer osr(__func__);
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    os->apply_transaction(&osr, std::move(t));
+    os->apply_transaction(ch, std::move(t));
   }
 
   // create the objects
@@ -273,19 +271,17 @@ int main(int argc, const char *argv[])
       oss << "osbench-thread-" << i;
       oids.emplace_back(hobject_t(sobject_t(oss.str(), CEPH_NOSNAP)));
 
-      ObjectStore::Sequencer osr(__func__);
       ObjectStore::Transaction t;
       t.touch(cid, oids[i]);
-      int r = os->apply_transaction(&osr, std::move(t));
+      int r = os->apply_transaction(ch, std::move(t));
       assert(r == 0);
     }
   } else {
     oids.emplace_back(hobject_t(sobject_t("osbench", CEPH_NOSNAP)));
 
-    ObjectStore::Sequencer osr(__func__);
     ObjectStore::Transaction t;
     t.touch(cid, oids.back());
-    int r = os->apply_transaction(&osr, std::move(t));
+    int r = os->apply_transaction(ch, std::move(t));
     assert(r == 0);
   }
 
@@ -314,11 +310,10 @@ int main(int argc, const char *argv[])
       << iops << " iops" << dendl;
 
   // remove the objects
-  ObjectStore::Sequencer osr(__func__);
   ObjectStore::Transaction t;
   for (const auto &oid : oids)
     t.remove(cid, oid);
-  os->apply_transaction(&osr,std::move(t));
+  os->apply_transaction(ch, std::move(t));
 
   os->umount();
   return 0;
index c0242dd77cf4a8b3c2e65cb6559f050843658554..93bd044ca15387ac28b168ca4e503d43cfee5dfc 100644 (file)
@@ -2317,11 +2317,11 @@ public:
   PGLogTestRebuildMissing() : PGLogTest(), StoreTestFixture("memstore") {}
   void SetUp() override {
     StoreTestFixture::SetUp();
-    ObjectStore::Sequencer osr(__func__);
     ObjectStore::Transaction t;
     test_coll = coll_t(spg_t(pg_t(1, 1)));
+    ch = store->create_new_collection(test_coll);
     t.create_collection(test_coll, 0);
-    store->apply_transaction(&osr, std::move(t));
+    store->apply_transaction(ch, std::move(t));
     existing_oid = mk_obj(0);
     nonexistent_oid = mk_obj(1);
     ghobject_t existing_ghobj(existing_oid);
@@ -2332,7 +2332,7 @@ public:
     ObjectStore::Transaction t2;
     t2.touch(test_coll, ghobject_t(existing_oid));
     t2.setattr(test_coll, ghobject_t(existing_oid), OI_ATTR, enc_oi);
-    ASSERT_EQ(0u, store->apply_transaction(&osr, std::move(t2)));
+    ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t2)));
     info.last_backfill = hobject_t::get_max();
     info.last_complete = eversion_t();
   }
@@ -2400,11 +2400,11 @@ public:
 
   void SetUp() override {
     StoreTestFixture::SetUp();
-    ObjectStore::Sequencer osr(__func__);
     ObjectStore::Transaction t;
     test_coll = coll_t(spg_t(pg_t(1, 1)));
+    auto ch = store->create_new_collection(test_coll);
     t.create_collection(test_coll, 0);
-    store->apply_transaction(&osr, std::move(t));
+    store->apply_transaction(ch, std::move(t));
   }
 
   void TearDown() override {
@@ -2479,7 +2479,6 @@ public:
   }
 
   void test_disk_roundtrip() {
-    ObjectStore::Sequencer osr(__func__);
     ObjectStore::Transaction t;
     hobject_t hoid;
     hoid.pool = 1;
@@ -2490,7 +2489,8 @@ public:
     if (!km.empty()) {
       t.omap_setkeys(test_coll, log_oid, km);
     }
-    ASSERT_EQ(0u, store->apply_transaction(&osr, std::move(t)));
+    auto ch = store->open_collection(test_coll);
+    ASSERT_EQ(0u, store->apply_transaction(ch, std::move(t)));
 
     auto orig_dups = log.dups;
     clear();
index 394b9892aaa8572211aa157982710048c87ed7bd..18a85e7e25c31ebb558240861f6589e1bd1f43ae 100644 (file)
@@ -57,11 +57,11 @@ int main(int argc, const char **argv)
     return -1;
   }
 
-  ObjectStore::Sequencer osr(__func__);
   ObjectStore::Transaction t;
   char buf[1 << 20];
   bufferlist bl;
   bl.append(buf, sizeof(buf));
+  auto ch = fs->create_new_collection(coll_t());
   t.create_collection(coll_t(), 0);
 
   for (int i=0; i<mb; i++) {
@@ -74,7 +74,7 @@ int main(int argc, const char **argv)
   dout(0) << "starting thread" << dendl;
   foo.create("foo");
   dout(0) << "starting op" << dendl;
-  fs->apply_transaction(&osr, std::move(t));
+  fs->apply_transaction(ch, std::move(t));
 
 }
 
index c7ef44f20dc31562f530fc36018ce26758bde686..41408f963a24c265c9887f50aebce6975d9028ff 100644 (file)
@@ -412,8 +412,7 @@ int mark_pg_for_removal(ObjectStore *fs, spg_t pgid, ObjectStore::Transaction *t
 #pragma GCC diagnostic pop
 #pragma GCC diagnostic warning "-Wpragmas"
 
-int initiate_new_remove_pg(ObjectStore *store, spg_t r_pgid,
-                          ObjectStore::Sequencer &osr)
+int initiate_new_remove_pg(ObjectStore *store, spg_t r_pgid)
 {
   if (!dry_run)
     finish_remove_pgs(store);
@@ -428,7 +427,8 @@ int initiate_new_remove_pg(ObjectStore *store, spg_t r_pgid,
   if (r < 0) {
     return r;
   }
-  store->apply_transaction(&osr, std::move(rmt));
+  ObjectStore::CollectionHandle ch = store->open_collection(coll_t(r_pgid));
+  store->apply_transaction(ch, std::move(rmt));
   finish_remove_pgs(store);
   return r;
 }
@@ -635,8 +635,7 @@ int ObjectStoreTool::export_files(ObjectStore *store, coll_t coll)
   return 0;
 }
 
-int set_inc_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl, bool force,
-                  ObjectStore::Sequencer &osr) {
+int set_inc_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl, bool force) {
   OSDMap::Incremental inc;
   bufferlist::iterator it = bl.begin();
   inc.decode(it);
@@ -661,10 +660,11 @@ int set_inc_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl, bool force,
   }
   if (dry_run)
     return 0;
+  ObjectStore::CollectionHandle ch = store->open_collection(coll_t::meta());
   ObjectStore::Transaction t;
   t.write(coll_t::meta(), inc_oid, 0, bl.length(), bl);
   t.truncate(coll_t::meta(), inc_oid, bl.length());
-  int ret = store->apply_transaction(&osr, std::move(t));
+  int ret = store->apply_transaction(ch, std::move(t));
   if (ret) {
     cerr << "Failed to set inc-osdmap (" << inc_oid << "): " << ret << std::endl;
   } else {
@@ -683,8 +683,7 @@ int get_inc_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl)
   return 0;
 }
 
-int set_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl, bool force,
-              ObjectStore::Sequencer &osr) {
+int set_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl, bool force) {
   OSDMap osdmap;
   osdmap.decode(bl);
   if (e == 0) {
@@ -709,9 +708,10 @@ int set_osdmap(ObjectStore *store, epoch_t e, bufferlist& bl, bool force,
   if (dry_run)
     return 0;
   ObjectStore::Transaction t;
+  ObjectStore::CollectionHandle ch = store->open_collection(coll_t::meta());
   t.write(coll_t::meta(), full_oid, 0, bl.length(), bl);
   t.truncate(coll_t::meta(), full_oid, bl.length());
-  int ret = store->apply_transaction(&osr, std::move(t));
+  int ret = store->apply_transaction(ch, std::move(t));
   if (ret) {
     cerr << "Failed to set osdmap (" << full_oid << "): " << ret << std::endl;
   } else {
@@ -1064,10 +1064,10 @@ int ObjectStoreTool::dump_object(Formatter *formatter,
   return 0;
 }
 
-int ObjectStoreTool::get_object(ObjectStore *store, coll_t coll,
+int ObjectStoreTool::get_object(ObjectStore *store,
+                               coll_t coll,
                                bufferlist &bl, OSDMap &curmap,
-                               bool *skipped_objects,
-                               ObjectStore::Sequencer &osr)
+                               bool *skipped_objects)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -1087,6 +1087,8 @@ int ObjectStoreTool::get_object(ObjectStore *store, coll_t coll,
     return -EFAULT;
   }
   assert(g_ceph_context);
+
+  auto ch = store->open_collection(coll);
   if (ob.hoid.hobj.nspace != g_ceph_context->_conf->osd_hit_set_namespace) {
     object_t oid = ob.hoid.hobj.oid;
     object_locator_t loc(ob.hoid.hobj);
@@ -1161,7 +1163,7 @@ int ObjectStoreTool::get_object(ObjectStore *store, coll_t coll,
     }
   }
   if (!dry_run)
-    store->apply_transaction(&osr, std::move(*t));
+    store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
@@ -1571,8 +1573,7 @@ int ObjectStoreTool::dump_import(Formatter *formatter)
 }
 
 int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb,
-                              bool force, std::string pgidstr,
-                              ObjectStore::Sequencer &osr)
+                              bool force, std::string pgidstr)
 {
   bufferlist ebl;
   pg_info_t info;
@@ -1690,8 +1691,10 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb,
     return -EEXIST;
   }
 
+  ObjectStore::CollectionHandle ch;
   if (!dry_run) {
     ObjectStore::Transaction t;
+    ch = store->create_new_collection(coll);
     PG::_create(t, pgid,
                pgid.get_split_bits(curmap.get_pg_pool(pgid.pool())->get_pg_num()));
     PG::_init(t, pgid, NULL);
@@ -1701,7 +1704,7 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb,
     encode((char)1, values["_remove"]);
     t.omap_setkeys(coll, pgid.make_pgmeta_oid(), values);
 
-    store->apply_transaction(&osr, std::move(t));
+    store->apply_transaction(ch, std::move(t));
   }
 
   cout << "Importing pgid " << pgid;
@@ -1727,7 +1730,7 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb,
     }
     switch(type) {
     case TYPE_OBJECT_BEGIN:
-      ret = get_object(store, coll, ebl, curmap, &skipped_objects, osr);
+      ret = get_object(store, coll, ebl, curmap, &skipped_objects);
       if (ret) return ret;
       break;
     case TYPE_PG_METADATA:
@@ -1819,7 +1822,7 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb,
     set<string> remove;
     remove.insert("_remove");
     t.omap_rmkeys(coll, pgid.make_pgmeta_oid(), remove);
-    store->apply_transaction(&osr, std::move(t));
+    store->apply_transaction(ch, std::move(t));
   }
 
   return 0;
@@ -1873,8 +1876,7 @@ int remove_object(coll_t coll, ghobject_t &ghobj,
 int get_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj, SnapSet &ss, bool silent);
 
 int do_remove_object(ObjectStore *store, coll_t coll,
-                    ghobject_t &ghobj, bool all, bool force,
-                    ObjectStore::Sequencer &osr)
+                    ghobject_t &ghobj, bool all, bool force)
 {
   spg_t pg;
   coll.is_pg_prefix(&pg);
@@ -1916,6 +1918,7 @@ int do_remove_object(ObjectStore *store, coll_t coll,
 
   cout << "remove " << ghobj << std::endl;
 
+  auto ch = store->open_collection(coll);
   if (!dry_run) {
     r = remove_object(coll, ghobj, mapper, &_t, &t);
     if (r < 0)
@@ -1935,7 +1938,7 @@ int do_remove_object(ObjectStore *store, coll_t coll,
   }
 
   if (!dry_run)
-    store->apply_transaction(&osr, std::move(t));
+    store->apply_transaction(ch, std::move(t));
 
   return 0;
 }
@@ -2026,8 +2029,7 @@ int do_get_bytes(ObjectStore *store, coll_t coll, ghobject_t &ghobj, int fd)
 }
 
 int do_set_bytes(ObjectStore *store, coll_t coll,
-                ghobject_t &ghobj, int fd,
-                ObjectStore::Sequencer &osr)
+                ghobject_t &ghobj, int fd)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -2062,8 +2064,9 @@ int do_set_bytes(ObjectStore *store, coll_t coll,
     // XXX: Should we apply_transaction() every once in a while for very large files
   } while(true);
 
+  auto ch = store->open_collection(coll);
   if (!dry_run)
-    store->apply_transaction(&osr, std::move(*t));
+    store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
@@ -2088,8 +2091,7 @@ int do_get_attr(ObjectStore *store, coll_t coll, ghobject_t &ghobj, string key)
 }
 
 int do_set_attr(ObjectStore *store, coll_t coll,
-               ghobject_t &ghobj, string key, int fd,
-               ObjectStore::Sequencer &osr)
+               ghobject_t &ghobj, string key, int fd)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -2109,13 +2111,13 @@ int do_set_attr(ObjectStore *store, coll_t coll,
 
   t->setattr(coll, ghobj, key,  bl);
 
-  store->apply_transaction(&osr, std::move(*t));
+  auto ch = store->open_collection(coll);
+  store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
 int do_rm_attr(ObjectStore *store, coll_t coll,
-              ghobject_t &ghobj, string key,
-              ObjectStore::Sequencer &osr)
+              ghobject_t &ghobj, string key)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -2128,7 +2130,8 @@ int do_rm_attr(ObjectStore *store, coll_t coll,
 
   t->rmattr(coll, ghobj, key);
 
-  store->apply_transaction(&osr, std::move(*t));
+  auto ch = store->open_collection(coll);
+  store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
@@ -2164,8 +2167,7 @@ int do_get_omap(ObjectStore *store, coll_t coll, ghobject_t &ghobj, string key)
 }
 
 int do_set_omap(ObjectStore *store, coll_t coll,
-               ghobject_t &ghobj, string key, int fd,
-               ObjectStore::Sequencer &osr)
+               ghobject_t &ghobj, string key, int fd)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -2188,13 +2190,13 @@ int do_set_omap(ObjectStore *store, coll_t coll,
 
   t->omap_setkeys(coll, ghobj, attrset);
 
-  store->apply_transaction(&osr, std::move(*t));
+  auto ch = store->open_collection(coll);
+  store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
 int do_rm_omap(ObjectStore *store, coll_t coll,
-              ghobject_t &ghobj, string key,
-              ObjectStore::Sequencer &osr)
+              ghobject_t &ghobj, string key)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -2210,7 +2212,8 @@ int do_rm_omap(ObjectStore *store, coll_t coll,
 
   t->omap_rmkeys(coll, ghobj, keys);
 
-  store->apply_transaction(&osr, std::move(*t));
+  auto ch = store->open_collection(coll);
+  store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
@@ -2235,8 +2238,7 @@ int do_get_omaphdr(ObjectStore *store, coll_t coll, ghobject_t &ghobj)
 }
 
 int do_set_omaphdr(ObjectStore *store, coll_t coll,
-                  ghobject_t &ghobj, int fd,
-                  ObjectStore::Sequencer &osr)
+                  ghobject_t &ghobj, int fd)
 {
   ObjectStore::Transaction tran;
   ObjectStore::Transaction *t = &tran;
@@ -2256,15 +2258,12 @@ int do_set_omaphdr(ObjectStore *store, coll_t coll,
 
   t->omap_setheader(coll, ghobj, hdrbl);
 
-  store->apply_transaction(&osr, std::move(*t));
+  auto ch = store->open_collection(coll);
+  store->apply_transaction(ch, std::move(*t));
   return 0;
 }
 
 struct do_fix_lost : public action_on_object_t {
-  ObjectStore::Sequencer *osr;
-
-  explicit do_fix_lost(ObjectStore::Sequencer *_osr) : osr(_osr) {}
-
   int call(ObjectStore *store, coll_t coll,
                   ghobject_t &ghobj, object_info_t &oi) override {
     if (oi.is_lost()) {
@@ -2279,7 +2278,8 @@ struct do_fix_lost : public action_on_object_t {
       encode(oi, bl, -1);  /* fixme: using full features */
       ObjectStore::Transaction t;
       t.setattr(coll, ghobj, OI_ATTR, bl);
-      int r = store->apply_transaction(osr, std::move(t));
+      auto ch = store->open_collection(coll);
+      int r = store->apply_transaction(ch, std::move(t));
       if (r < 0) {
        cerr << "Error getting fixing attr on : " << make_pair(coll, ghobj)
             << ", "
@@ -2373,8 +2373,9 @@ int print_obj_info(ObjectStore *store, coll_t coll, ghobject_t &ghobj, Formatter
   return r;
 }
 
-int set_size(ObjectStore *store, coll_t coll, ghobject_t &ghobj, uint64_t setsize, Formatter* formatter,
-            ObjectStore::Sequencer &osr, bool corrupt)
+int set_size(
+  ObjectStore *store, coll_t coll, ghobject_t &ghobj, uint64_t setsize, Formatter* formatter,
+  bool corrupt)
 {
   if (ghobj.hobj.is_snapdir()) {
     cerr << "Can't set the size of a snapdir" << std::endl;
@@ -2463,7 +2464,8 @@ int set_size(ObjectStore *store, coll_t coll, ghobject_t &ghobj, uint64_t setsiz
       encode(ss, snapattr);
       t.setattr(coll, head, SS_ATTR, snapattr);
     }
-    r = store->apply_transaction(&osr, std::move(t));
+    auto ch = store->open_collection(coll);
+    r = store->apply_transaction(ch, std::move(t));
     if (r < 0) {
       cerr << "Error writing object info: " << make_pair(coll, ghobj) << ", "
          << cpp_strerror(r) << std::endl;
@@ -2474,7 +2476,7 @@ int set_size(ObjectStore *store, coll_t coll, ghobject_t &ghobj, uint64_t setsiz
 }
 
 int clear_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj,
-                  string arg, ObjectStore::Sequencer &osr)
+                  string arg)
 {
   SnapSet ss;
   int ret = get_snapset(store, coll, ghobj, ss);
@@ -2509,7 +2511,8 @@ int clear_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj,
     encode(ss, bl);
     ObjectStore::Transaction t;
     t.setattr(coll, ghobj, SS_ATTR, bl);
-    int r = store->apply_transaction(&osr, std::move(t));
+    auto ch = store->open_collection(coll);
+    int r = store->apply_transaction(ch, std::move(t));
     if (r < 0) {
       cerr << "Error setting snapset on : " << make_pair(coll, ghobj) << ", "
           << cpp_strerror(r) << std::endl;
@@ -2554,8 +2557,8 @@ int remove_from(T &mv, string name, snapid_t cloneid, bool force)
   return 0;
 }
 
-int remove_clone(ObjectStore *store, coll_t coll, ghobject_t &ghobj, snapid_t cloneid, bool force,
-                    ObjectStore::Sequencer &osr)
+int remove_clone(
+  ObjectStore *store, coll_t coll, ghobject_t &ghobj, snapid_t cloneid, bool force)
 {
   // XXX: Don't allow this if in a cache tier or former cache tier
   // bool allow_incomplete_clones() const {
@@ -2607,7 +2610,8 @@ int remove_clone(ObjectStore *store, coll_t coll, ghobject_t &ghobj, snapid_t cl
   encode(snapset, bl);
   ObjectStore::Transaction t;
   t.setattr(coll, ghobj, SS_ATTR, bl);
-  int r = store->apply_transaction(&osr, std::move(t));
+  auto ch = store->open_collection(coll);
+  int r = store->apply_transaction(ch, std::move(t));
   if (r < 0) {
     cerr << "Error setting snapset on : " << make_pair(coll, ghobj) << ", "
         << cpp_strerror(r) << std::endl;
@@ -2623,7 +2627,6 @@ int dup(string srcpath, ObjectStore *src, string dstpath, ObjectStore *dst)
   cout << "dup from " << src->get_type() << ": " << srcpath << "\n"
        << "      to " << dst->get_type() << ": " << dstpath
        << std::endl;
-  ObjectStore::Sequencer osr("dup");
   int num, i;
   vector<coll_t> collections;
   int r;
@@ -2668,6 +2671,7 @@ int dup(string srcpath, ObjectStore *src, string dstpath, ObjectStore *dst)
   i = 1;
   for (auto cid : collections) {
     cout << i++ << "/" << num << " " << cid << std::endl;
+    auto ch = dst->create_new_collection(cid);
     {
       ObjectStore::Transaction t;
       int bits = src->collection_bits(cid);
@@ -2681,7 +2685,7 @@ int dup(string srcpath, ObjectStore *src, string dstpath, ObjectStore *dst)
         }
       }
       t.create_collection(cid, bits);
-      dst->apply_transaction(&osr, std::move(t));
+      dst->apply_transaction(ch, std::move(t));
     }
 
     ghobject_t pos;
@@ -2737,7 +2741,7 @@ int dup(string srcpath, ObjectStore *src, string dstpath, ObjectStore *dst)
          t.omap_setkeys(cid, oid, omap);
        }
 
-       dst->apply_transaction(&osr, std::move(t));
+       dst->apply_transaction(ch, std::move(t));
       }
     }
     cout << "  " << std::setw(16) << n << " objects, "
@@ -3260,7 +3264,6 @@ int main(int argc, char **argv)
     return 0;
   }
 
-  ObjectStore::Sequencer *osr = new ObjectStore::Sequencer(__func__);
   int ret = fs->mount();
   if (ret < 0) {
     if (ret == -EBUSY) {
@@ -3444,7 +3447,7 @@ int main(int argc, char **argv)
   if (op == "import") {
 
     try {
-      ret = tool.do_import(fs, superblock, force, pgidstr, *osr);
+      ret = tool.do_import(fs, superblock, force, pgidstr);
     }
     catch (const buffer::error &e) {
       cerr << "do_import threw exception error " << e.what() << std::endl;
@@ -3494,7 +3497,7 @@ int main(int argc, char **argv)
     if (ret < 0) {
       cerr << "Failed to read osdmap " << cpp_strerror(ret) << std::endl;
     } else {
-      ret = set_osdmap(fs, epoch, bl, force, *osr);
+      ret = set_osdmap(fs, epoch, bl, force);
     }
     goto out;
   } else if (op == "get-inc-osdmap") {
@@ -3522,7 +3525,7 @@ int main(int argc, char **argv)
       cerr << "Failed to read incremental osdmap  " << cpp_strerror(ret) << std::endl;
       goto out;
     } else {
-      ret = set_inc_osdmap(fs, epoch, bl, force, *osr);
+      ret = set_inc_osdmap(fs, epoch, bl, force);
     }
     goto out;
   } else if (op == "update-mon-db") {
@@ -3541,7 +3544,7 @@ int main(int argc, char **argv)
       ret = -EINVAL;
       goto out;
     }
-    ret = initiate_new_remove_pg(fs, pgid, *osr);
+    ret = initiate_new_remove_pg(fs, pgid);
     if (ret < 0) {
       cerr << "PG '" << pgid << "' not found" << std::endl;
       goto out;
@@ -3552,7 +3555,7 @@ int main(int argc, char **argv)
 
   if (op == "fix-lost") {
     boost::scoped_ptr<action_on_object_t> action;
-    action.reset(new do_fix_lost(osr));
+    action.reset(new do_fix_lost());
     if (pgidstr.length())
       ret = action_on_all_objects_in_exact_pg(fs, coll_t(pgid), *action, debug);
     else
@@ -3651,7 +3654,7 @@ int main(int argc, char **argv)
       ret = 0;
       if (objcmd == "remove" || objcmd == "removeall") {
         bool all = (objcmd == "removeall");
-        ret = do_remove_object(fs, coll, ghobj, all, force, *osr);
+        ret = do_remove_object(fs, coll, ghobj, all, force);
         goto out;
       } else if (objcmd == "list-attrs") {
         ret = do_list_attrs(fs, coll, ghobj);
@@ -3693,7 +3696,7 @@ int main(int argc, char **argv)
               goto out;
             }
           }
-          ret = do_set_bytes(fs, coll, ghobj, fd, *osr);
+          ret = do_set_bytes(fs, coll, ghobj, fd);
           if (fd != STDIN_FILENO)
             close(fd);
         }
@@ -3729,7 +3732,7 @@ int main(int argc, char **argv)
            goto out;
          }
        }
-       ret = do_set_attr(fs, coll, ghobj, arg1, fd, *osr);
+       ret = do_set_attr(fs, coll, ghobj, arg1, fd);
        if (fd != STDIN_FILENO)
          close(fd);
         goto out;
@@ -3739,7 +3742,7 @@ int main(int argc, char **argv)
           ret = 1;
           goto out;
         }
-       ret = do_rm_attr(fs, coll, ghobj, arg1, *osr);
+       ret = do_rm_attr(fs, coll, ghobj, arg1);
         goto out;
       } else if (objcmd == "get-omap") {
        if (vm.count("arg1") == 0) {
@@ -3772,7 +3775,7 @@ int main(int argc, char **argv)
            goto out;
          }
        }
-       ret = do_set_omap(fs, coll, ghobj, arg1, fd, *osr);
+       ret = do_set_omap(fs, coll, ghobj, arg1, fd);
        if (fd != STDIN_FILENO)
          close(fd);
         goto out;
@@ -3782,7 +3785,7 @@ int main(int argc, char **argv)
           ret = 1;
           goto out;
         }
-       ret = do_rm_omap(fs, coll, ghobj, arg1, *osr);
+       ret = do_rm_omap(fs, coll, ghobj, arg1);
         goto out;
       } else if (objcmd == "get-omaphdr") {
        if (vm.count("arg1")) {
@@ -3816,7 +3819,7 @@ int main(int argc, char **argv)
            goto out;
          }
        }
-       ret = do_set_omaphdr(fs, coll, ghobj, fd, *osr);
+       ret = do_set_omaphdr(fs, coll, ghobj, fd);
        if (fd != STDIN_FILENO)
          close(fd);
         goto out;
@@ -3844,7 +3847,7 @@ int main(int argc, char **argv)
          goto out;
        }
        uint64_t size = atoll(arg1.c_str());
-       ret = set_size(fs, coll, ghobj, size, formatter, *osr, corrupt);
+       ret = set_size(fs, coll, ghobj, size, formatter, corrupt);
        goto out;
       } else if (objcmd == "clear-snapset") {
         // UNDOCUMENTED: For testing zap SnapSet
@@ -3854,7 +3857,7 @@ int main(int argc, char **argv)
          ret = 1;
          goto out;
        }
-        ret = clear_snapset(fs, coll, ghobj, arg1, *osr);
+        ret = clear_snapset(fs, coll, ghobj, arg1);
         goto out;
       } else if (objcmd == "remove-clone-metadata") {
         // Extra arg
@@ -3874,7 +3877,7 @@ int main(int argc, char **argv)
          goto out;
        }
         snapid_t cloneid = atoi(arg1.c_str());
-       ret = remove_clone(fs, coll, ghobj, cloneid, force, *osr);
+       ret = remove_clone(fs, coll, ghobj, cloneid, force);
        goto out;
       }
       cerr << "Unknown object command '" << objcmd << "'" << std::endl;
@@ -3911,7 +3914,7 @@ int main(int argc, char **argv)
       if (ret == 0) {
         cerr << "Export successful" << std::endl;
         if (op == "export-remove") {
-          ret = initiate_new_remove_pg(fs, pgid, *osr);
+          ret = initiate_new_remove_pg(fs, pgid);
           // Export succeeded, so pgid is there
           assert(ret == 0);
           cerr << "Remove successful" << std::endl;
@@ -3956,7 +3959,8 @@ int main(int argc, char **argv)
        ret = write_info(*t, map_epoch, info, past_intervals);
        if (ret != 0)
          goto out;
-       fs->apply_transaction(osr, std::move(*t));
+       auto ch = fs->open_collection(coll_t(pgid));
+       fs->apply_transaction(ch, std::move(*t));
       }
       cout << "Marking complete succeeded" << std::endl;
     } else {
@@ -3969,7 +3973,6 @@ int main(int argc, char **argv)
 
 out:
   int r = fs->umount();
-  delete osr;
   if (r < 0) {
     cerr << "umount failed: " << cpp_strerror(r) << std::endl;
     // If no previous error, then use umount() error
index 4072c35ed3b4ac74bf1fd8e581dc3c5c69a38408..74565ba36f2261ac4f1fcb81ac8aafc5ef20c146 100644 (file)
@@ -26,8 +26,7 @@ class ObjectStoreTool : public RadosDump
 
     int dump_import(Formatter *formatter);
     int do_import(ObjectStore *store, OSDSuperblock& sb, bool force,
-                 std::string pgidstr,
-                 ObjectStore::Sequencer &osr);
+                 std::string pgidstr);
     int do_export(ObjectStore *fs, coll_t coll, spg_t pgid,
           pg_info_t &info, epoch_t map_epoch, __u8 struct_ver,
           const OSDSuperblock& superblock,
@@ -36,8 +35,7 @@ class ObjectStoreTool : public RadosDump
                                bufferlist &bl);
     int get_object(
       ObjectStore *store, coll_t coll,
-      bufferlist &bl, OSDMap &curmap, bool *skipped_objects,
-      ObjectStore::Sequencer &osr);
+      bufferlist &bl, OSDMap &curmap, bool *skipped_objects);
     int export_file(
         ObjectStore *store, coll_t cid, ghobject_t &obj);
     int export_files(ObjectStore *store, coll_t coll);