#if defined(HAVE_LIBAIO)
   // first try bluestore -- it has a crc on its header and will fail
   // reliably.
-  r = BlueStore::get_block_device_fsid(path, fsid);
+  r = BlueStore::get_block_device_fsid(cct, path, fsid);
   if (r == 0) {
     lgeneric_dout(cct, 0) << __func__ << " " << path << " is bluestore, "
                          << *fsid << dendl;
 
 #include "BitMapAllocator.h"
 #include "common/debug.h"
 
-#define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_bluestore
 
-Allocator *Allocator::create(string type,
+Allocator *Allocator::create(CephContext* cct, string type,
                              int64_t size, int64_t block_size)
 {
   if (type == "stupid") {
-    return new StupidAllocator;
+    return new StupidAllocator(cct);
   } else if (type == "bitmap") {
-    return new BitMapAllocator(size, block_size);
+    return new BitMapAllocator(cct, size, block_size);
   }
-  derr << "Allocator::" << __func__ << " unknown alloc type " << type << dendl;
-  return NULL;
+  lderr(cct) << "Allocator::" << __func__ << " unknown alloc type "
+            << type << dendl;
+  return nullptr;
 }
 
   virtual uint64_t get_free() = 0;
 
   virtual void shutdown() = 0;
-  static Allocator *create(string type, int64_t size, int64_t block_size);
+  static Allocator *create(CephContext* cct, string type, int64_t size,
+                          int64_t block_size);
 };
 
 #endif
 
 #include "common/debug.h"
 #include <math.h>
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluestore
 #undef dout_prefix
 #define dout_prefix *_dout << "bitalloc:"
 /*
  * Bitmap Entry functions.
  */
-
 void BmapEntry::_init_bit_mask()
 {
 
 
   uint64_t bmask = ((bmap_t) 0x1 << (BmapEntry::size() - 1));
   for (int i = 0; i < BmapEntry::size(); i++) {
-    m_bit_to_mask[i] = bmask >> i; 
+    m_bit_to_mask[i] = bmask >> i;
   }
   BmapEntry::m_bit_mask_init = true;
 }
 
-BmapEntry::BmapEntry(bool full)
+BmapEntry::BmapEntry(CephContext* cct, bool full)
+  : cct(cct)
 {
 
   BmapEntry::_init_bit_mask();
   alloc_assert(total_blocks < std::numeric_limits<int32_t>::max());
   alloc_assert(!(total_blocks % BmapEntry::size()));
 
-  BmapEntryVector *bmaps = new BmapEntryVector(num_bmaps, BmapEntry(def));
+  BmapEntryVector *bmaps = new BmapEntryVector(num_bmaps, BmapEntry(cct, def));
   m_bmap_list = bmaps;
   incr_count();
 }
   return 0;
 }
 
-BitMapZone::BitMapZone(int64_t total_blocks, int64_t zone_num)
+BitMapZone::BitMapZone(CephContext* cct, int64_t total_blocks,
+                      int64_t zone_num)
+  : BitMapArea(cct)
 {
   init(zone_num, total_blocks, false);
 }
 
-BitMapZone::BitMapZone(int64_t total_blocks, int64_t zone_num, bool def)
+BitMapZone::BitMapZone(CephContext* cct, int64_t total_blocks,
+                      int64_t zone_num, bool def)
+  : BitMapArea(cct)
 {
   init(zone_num, total_blocks, def);
 }
 /*
  * BitMapArea Leaf and non-Leaf functions.
  */
-int64_t BitMapArea::get_zone_size()
+int64_t BitMapArea::get_zone_size(CephContext* cct)
 {
-  return g_conf->bluestore_bitmapallocator_blocks_per_zone;
+  return cct->_conf->bluestore_bitmapallocator_blocks_per_zone;
 }
 
-int64_t BitMapArea::get_span_size()
+int64_t BitMapArea::get_span_size(CephContext* cct)
 {
-  return g_conf->bluestore_bitmapallocator_span_size;
+  return cct->_conf->bluestore_bitmapallocator_span_size;
 }
 
 bmap_area_type_t BitMapArea::level_to_type(int level)
   }
 }
 
-int BitMapArea::get_level(int64_t total_blocks)
+int BitMapArea::get_level(CephContext* cct, int64_t total_blocks)
 {
   int level = 1;
-  int64_t zone_size_block = get_zone_size();
-  int64_t span_size = get_span_size();
+  int64_t zone_size_block = get_zone_size(cct);
+  int64_t span_size = get_span_size(cct);
   int64_t spans = zone_size_block * span_size;
   while (spans < total_blocks) {
     spans *= span_size;
   return level;
 }
 
-int64_t BitMapArea::get_level_factor(int level)
+int64_t BitMapArea::get_level_factor(CephContext* cct, int level)
 {
   alloc_assert(level > 0);
 
-  int64_t zone_size = get_zone_size();
+  int64_t zone_size = get_zone_size(cct);
   if (level == 1) {
     return zone_size;
   }
 
   int64_t level_factor = zone_size;
-  int64_t span_size = get_span_size();
+  int64_t span_size = get_span_size(cct);
   while (--level) {
     level_factor *= span_size;
   }
 /*
  * BitMapArea Leaf and Internal
  */
-BitMapAreaIN::BitMapAreaIN()
+BitMapAreaIN::BitMapAreaIN(CephContext* cct)
+  : BitMapArea(cct)
 {
   // nothing
 }
 {
   m_area_index = area_idx;
   m_total_blocks = total_blocks;
-  m_level = BitMapArea::get_level(total_blocks);
+  m_level = BitMapArea::get_level(cct, total_blocks);
   m_type = BitMapArea::level_to_type(m_level);
   m_reserved_blocks = 0;
 
   alloc_assert(!(total_blocks % BmapEntry::size()));
 
   init_common(total_blocks, area_idx, def);
-  int64_t level_factor = BitMapArea::get_level_factor(m_level);
+  int64_t level_factor = BitMapArea::get_level_factor(cct, m_level);
 
   num_child = (total_blocks + level_factor - 1) / level_factor;
   alloc_assert(num_child < std::numeric_limits<int16_t>::max());
   int i = 0;
   for (i = 0; i < num_child - 1; i++) {
     if (m_level <= 2) {
-      children[i] = new BitMapAreaLeaf(m_child_size_blocks, i, def);
+      children[i] = new BitMapAreaLeaf(cct, m_child_size_blocks, i, def);
     } else {
-      children[i] = new BitMapAreaIN(m_child_size_blocks, i, def);
+      children[i] = new BitMapAreaIN(cct, m_child_size_blocks, i, def);
     }
     total_blocks -= m_child_size_blocks;
   }
 
-  int last_level = BitMapArea::get_level(total_blocks);
+  int last_level = BitMapArea::get_level(cct, total_blocks);
   if (last_level == 1) {
-    children[i] = new BitMapAreaLeaf(total_blocks, i, def);
+    children[i] = new BitMapAreaLeaf(cct, total_blocks, i, def);
   } else {
-    children[i] = new BitMapAreaIN(total_blocks, i, def);
+    children[i] = new BitMapAreaIN(cct, total_blocks, i, def);
   }
   BitMapAreaList *list = new BitMapAreaList(children, num_child);
   m_child_list = list;
   m_num_child = num_child;
 }
 
-BitMapAreaIN::BitMapAreaIN(int64_t total_blocks, int64_t area_idx)
+BitMapAreaIN::BitMapAreaIN(CephContext* cct,int64_t total_blocks,
+                          int64_t area_idx)
+  : BitMapArea(cct)
 {
   init(total_blocks, area_idx, false);
 }
 
-BitMapAreaIN::BitMapAreaIN(int64_t total_blocks, int64_t area_idx, bool def)
+BitMapAreaIN::BitMapAreaIN(CephContext* cct, int64_t total_blocks,
+                          int64_t area_idx, bool def)
+  : BitMapArea(cct)
 {
   init(total_blocks, area_idx, def);
 }
 /*
  * BitMapArea Leaf
  */
-BitMapAreaLeaf::BitMapAreaLeaf(int64_t total_blocks, int64_t area_idx)
+BitMapAreaLeaf::BitMapAreaLeaf(CephContext* cct, int64_t total_blocks,
+                              int64_t area_idx)
+  : BitMapAreaIN(cct)
 {
   init(total_blocks, area_idx, false);
 }
 
-BitMapAreaLeaf::BitMapAreaLeaf(int64_t total_blocks, int64_t area_idx, bool def)
+BitMapAreaLeaf::BitMapAreaLeaf(CephContext* cct, int64_t total_blocks,
+                              int64_t area_idx, bool def)
+  : BitMapAreaIN(cct)
 {
   init(total_blocks, area_idx, def);
 }
 
 void BitMapAreaLeaf::init(int64_t total_blocks, int64_t area_idx,
-          bool def)
+                         bool def)
 {
   int64_t num_child = 0;
   alloc_assert(!(total_blocks % BmapEntry::size()));
 
   init_common(total_blocks, area_idx, def);
   alloc_assert(m_level == 1);
-  int zone_size_block = get_zone_size();
+  int zone_size_block = get_zone_size(cct);
   alloc_assert(zone_size_block > 0);
   num_child = (total_blocks + zone_size_block - 1) / zone_size_block;
   alloc_assert(num_child);
   alloc_assert(m_level == 1);
   BitMapArea **children = new BitMapArea*[num_child];
   for (int i = 0; i < num_child; i++) {
-      children[i] = new BitMapZone(m_child_size_blocks, i, def);
+    children[i] = new BitMapZone(cct, m_child_size_blocks, i, def);
   }
 
   BitMapAreaList *list = new BitMapAreaList(children, num_child);
 /*
  * Main allocator functions.
  */
-BitAllocator::BitAllocator(int64_t total_blocks, int64_t zone_size_block, bmap_alloc_mode_t mode)
+BitAllocator::BitAllocator(CephContext* cct, int64_t total_blocks,
+                          int64_t zone_size_block, bmap_alloc_mode_t mode)
+  : BitMapAreaIN(cct)
 {
   init_check(total_blocks, zone_size_block, mode, false, false);
 }
 
-BitAllocator::BitAllocator(int64_t total_blocks, int64_t zone_size_block,
-         bmap_alloc_mode_t mode, bool def)
+BitAllocator::BitAllocator(CephContext* cct, int64_t total_blocks,
+                          int64_t zone_size_block, bmap_alloc_mode_t mode,
+                          bool def)
+  : BitMapAreaIN(cct)
 {
   init_check(total_blocks, zone_size_block, mode, def, false);
 }
 
-BitAllocator::BitAllocator(int64_t total_blocks, int64_t zone_size_block,
-         bmap_alloc_mode_t mode, bool def, bool stats_on)
+BitAllocator::BitAllocator(CephContext* cct, int64_t total_blocks,
+                          int64_t zone_size_block, bmap_alloc_mode_t mode,
+                          bool def, bool stats_on)
+  : BitMapAreaIN(cct)
 {
   init_check(total_blocks, zone_size_block, mode, def, stats_on);
 }
     return false;
   }
 
-  if (num_blocks > get_zone_size()) {
+  if (num_blocks > get_zone_size(cct)) {
     return false;
   }
   return true;
 
 typedef mempool::bluestore_alloc::vector<bmap_t> bmap_mask_vec_t;
 
 class BmapEntry {
+  CephContext* cct;
 
 private:
   bmap_t m_bits;
   static bmap_t align_mask(int x);
   static bmap_t bit_mask(int bit_num);
   bmap_t atomic_fetch();
-  BmapEntry(bool val);
-  BmapEntry() {
+  BmapEntry(CephContext* cct, bool val);
+  BmapEntry(CephContext* cct) : cct(cct) {
     m_bits = 0;
   }
   BmapEntry(const BmapEntry& bmap) {
+    cct = bmap.cct;
     bmap_t i = bmap.m_bits;
     m_bits = i;
   }
 } bmap_area_type_t;
 
 class BitMapArea {
+public:
+  CephContext* cct;
 
 protected:
   int16_t m_area_index;
 
 public:
   MEMPOOL_CLASS_HELPERS();
-  static int64_t get_zone_size();
-  static int64_t get_span_size();
+  static int64_t get_zone_size(CephContext* cct);
+  static int64_t get_span_size(CephContext* cct);
   bmap_area_type_t level_to_type(int level);
-  static int get_level(int64_t total_blocks);
-  static int64_t get_level_factor(int level);
+  static int get_level(CephContext* cct, int64_t total_blocks);
+  static int64_t get_level_factor(CephContext* cct, int level);
   virtual bool is_allocated(int64_t start_block, int64_t num_blocks) = 0;
   virtual bool is_exhausted() = 0;
   virtual bool child_check_n_lock(BitMapArea *child, int64_t required) {
   int64_t get_level();
   bmap_area_type_t get_type();
   virtual void dump_state(int& count) = 0;
+  BitMapArea(CephContext* cct) : cct(cct) {}
   virtual ~BitMapArea() { }
 };
 
   void free_blocks_int(int64_t start_block, int64_t num_blocks);
   void init(int64_t zone_num, int64_t total_blocks, bool def);
 
-  BitMapZone(int64_t total_blocks, int64_t zone_num);
-  BitMapZone(int64_t total_blocks, int64_t zone_num, bool def);
+  BitMapZone(CephContext* cct, int64_t total_blocks, int64_t zone_num);
+  BitMapZone(CephContext* cct, int64_t total_blocks, int64_t zone_num, bool def);
 
   ~BitMapZone();
   void shutdown();
   int64_t alloc_blocks_dis_int_work(bool wrap, int64_t num_blocks, int64_t min_alloc, int64_t hint,
         int64_t blk_off, ExtentList *block_list);  
 
+  int64_t alloc_blocks_int_work(bool wait, bool wrap,
+                         int64_t num_blocks, int64_t hint, int64_t *start_block);
+
 public:
   MEMPOOL_CLASS_HELPERS();
-  BitMapAreaIN();
-  BitMapAreaIN(int64_t zone_num, int64_t total_blocks);
-  BitMapAreaIN(int64_t zone_num, int64_t total_blocks, bool def);
+  BitMapAreaIN(CephContext* cct);
+  BitMapAreaIN(CephContext* cct, int64_t zone_num, int64_t total_blocks);
+  BitMapAreaIN(CephContext* cct, int64_t zone_num, int64_t total_blocks,
+              bool def);
 
   virtual ~BitMapAreaIN();
   void shutdown();
   MEMPOOL_CLASS_HELPERS();
   static int64_t count;
   static void incr_count() { count++;}
-  BitMapAreaLeaf() { }
-  BitMapAreaLeaf(int64_t zone_num, int64_t total_blocks);
-  BitMapAreaLeaf(int64_t zone_num, int64_t total_blocks, bool def);
+  BitMapAreaLeaf(CephContext* cct) : BitMapAreaIN(cct) { }
+  BitMapAreaLeaf(CephContext* cct, int64_t zone_num, int64_t total_blocks);
+  BitMapAreaLeaf(CephContext* cct, int64_t zone_num, int64_t total_blocks,
+                bool def);
 
   bool child_check_n_lock(BitMapArea *child, int64_t required) {
     ceph_abort();
 public:
   MEMPOOL_CLASS_HELPERS();
 
-  BitAllocator(int64_t total_blocks, int64_t zone_size_block, bmap_alloc_mode_t mode);
-  BitAllocator(int64_t total_blocks, int64_t zone_size_block, bmap_alloc_mode_t mode, bool def);
-  BitAllocator(int64_t total_blocks, int64_t zone_size_block,
+  BitAllocator(CephContext* cct, int64_t total_blocks,
+              int64_t zone_size_block, bmap_alloc_mode_t mode);
+  BitAllocator(CephContext* cct, int64_t total_blocks, int64_t zone_size_block,
+              bmap_alloc_mode_t mode, bool def);
+  BitAllocator(CephContext* cct, int64_t total_blocks, int64_t zone_size_block,
                bmap_alloc_mode_t mode, bool def, bool stats_on);
   ~BitAllocator();
   void shutdown();
 
 #include "bluestore_types.h"
 #include "common/debug.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluestore
 #undef dout_prefix
 #define dout_prefix *_dout << "bitmapalloc:"
 
 
-BitMapAllocator::BitMapAllocator(int64_t device_size, int64_t block_size)
+BitMapAllocator::BitMapAllocator(CephContext* cct, int64_t device_size,
+                                int64_t block_size)
+  : cct(cct)
 {
   assert(ISP2(block_size));
   if (!ISP2(block_size)) {
     return;
   }
 
-  int64_t zone_size_blks = g_conf->bluestore_bitmapallocator_blocks_per_zone;
+  int64_t zone_size_blks = cct->_conf->bluestore_bitmapallocator_blocks_per_zone;
   assert(ISP2(zone_size_blks));
   if (!ISP2(zone_size_blks)) {
     derr << __func__ << " zone_size " << zone_size_blks
     return;
   }
 
-  int64_t span_size = g_conf->bluestore_bitmapallocator_span_size;
+  int64_t span_size = cct->_conf->bluestore_bitmapallocator_span_size;
   assert(ISP2(span_size));
   if (!ISP2(span_size)) {
     derr << __func__ << " span_size " << span_size
   }
 
   m_block_size = block_size;
-  m_bit_alloc = new BitAllocator(device_size / block_size,
-        zone_size_blks, CONCURRENT, true);
+  m_bit_alloc = new BitAllocator(cct, device_size / block_size,
+                                zone_size_blks, CONCURRENT, true);
   assert(m_bit_alloc);
   if (!m_bit_alloc) {
     derr << __func__ << " Unable to intialize Bit Allocator" << dendl;
 
 #include "include/btree_interval_set.h"
 
 class BitMapAllocator : public Allocator {
+  CephContext* cct;
   std::mutex m_lock;
 
   int64_t m_block_size;
                         int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
 
 public:
-  BitMapAllocator();
-  BitMapAllocator(int64_t device_size, int64_t block_size);
+  BitMapAllocator(CephContext* cct, int64_t device_size, int64_t block_size);
   ~BitMapAllocator();
 
   int reserve(uint64_t need);
 
 
 #include "common/debug.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluestore
 #undef dout_prefix
 #define dout_prefix *_dout << "freelist "
   db->set_merge_operator(prefix, merge_op);
 }
 
-BitmapFreelistManager::BitmapFreelistManager(KeyValueDB *db,
+BitmapFreelistManager::BitmapFreelistManager(CephContext* cct,
+                                            KeyValueDB *db,
                                             string meta_prefix,
                                             string bitmap_prefix)
-  : meta_prefix(meta_prefix),
+  : FreelistManager(cct),
+    meta_prefix(meta_prefix),
     bitmap_prefix(bitmap_prefix),
     kvdb(db)
 {
 
 int BitmapFreelistManager::create(uint64_t new_size, KeyValueDB::Transaction txn)
 {
-  bytes_per_block = g_conf->bdev_block_size;
+  bytes_per_block = cct->_conf->bdev_block_size;
   assert(ISP2(bytes_per_block));
   size = P2ALIGN(new_size, bytes_per_block);
-  blocks_per_key = g_conf->bluestore_freelist_blocks_per_key;
+  blocks_per_key = cct->_conf->bluestore_freelist_blocks_per_key;
 
   _init_misc();
 
 {
   dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
           << std::dec << dendl;
-  if (g_conf->bluestore_debug_freelist)
+  if (cct->_conf->bluestore_debug_freelist)
     _verify_range(offset, length, 0);
   _xor(offset, length, txn);
 }
 {
   dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
           << std::dec << dendl;
-  if (g_conf->bluestore_debug_freelist)
+  if (cct->_conf->bluestore_debug_freelist)
     _verify_range(offset, length, 1);
   _xor(offset, length, txn);
 }
 
     KeyValueDB::Transaction txn);
 
 public:
-  BitmapFreelistManager(KeyValueDB *db, string meta_prefix,
+  BitmapFreelistManager(CephContext* cct, KeyValueDB *db, string meta_prefix,
                        string bitmap_prefix);
 
   static void setup_merge_operator(KeyValueDB *db, string prefix);
 
 
 #include "common/debug.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bdev
 #undef dout_prefix
 #define dout_prefix *_dout << "bdev "
   dout(20) << __func__ << " " << this << " done" << dendl;
 }
 
-BlockDevice *BlockDevice::create(const string& path, aio_callback_t cb, void *cbpriv)
+BlockDevice *BlockDevice::create(CephContext* cct, const string& path,
+                                aio_callback_t cb, void *cbpriv)
 {
   string type = "kernel";
   char buf[PATH_MAX + 1];
   dout(1) << __func__ << " path " << path << " type " << type << dendl;
 
   if (type == "kernel") {
-    return new KernelDevice(cb, cbpriv);
+    return new KernelDevice(cct, cb, cbpriv);
   }
 #if defined(HAVE_SPDK)
   if (type == "ust-nvme") {
-    return new NVMEDevice(cb, cbpriv);
+    return new NVMEDevice(cct, cb, cbpriv);
   }
 #endif
 
 
 
 /// track in-flight io
 struct IOContext {
+  CephContext* cct;
   void *priv;
 #ifdef HAVE_SPDK
   void *nvme_task_first = nullptr;
   std::atomic_int num_reading = {0};
   std::atomic_int num_waiting = {0};
 
-  explicit IOContext(void *p)
-    : priv(p)
+  explicit IOContext(CephContext* cct, void *p)
+    : cct(cct), priv(p)
     {}
 
   // no copying
-  IOContext(const IOContext& other);
-  IOContext &operator=(const IOContext& other);
+  IOContext(const IOContext& other) = delete;
+  IOContext &operator=(const IOContext& other) = delete;
 
   bool has_pending_aios() {
     return num_pending.load();
 
 
 class BlockDevice {
+public:
+  CephContext* cct;
+private:
   std::mutex ioc_reap_lock;
   vector<IOContext*> ioc_reap_queue;
   std::atomic_int ioc_reap_count = {0};
   bool rotational = true;
 
 public:
-  BlockDevice() = default;
+  BlockDevice(CephContext* cct) : cct(cct) {}
   virtual ~BlockDevice() = default;
   typedef void (*aio_callback_t)(void *handle, void *aio);
 
   static BlockDevice *create(
-      const string& path, aio_callback_t cb, void *cbpriv);
+    CephContext* cct, const string& path, aio_callback_t cb, void *cbpriv);
   virtual bool supported_bdev_label() { return true; }
   virtual bool is_rotational() { return rotational; }
 
 
 #include "BlockDevice.h"
 #include "Allocator.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluefs
 #undef dout_prefix
 #define dout_prefix *_dout << "bluefs "
 MEMPOOL_DEFINE_OBJECT_FACTORY(BlueFS::FileLock, bluefs_file_lock, bluefs);
 
 
-BlueFS::BlueFS()
-  : bdev(MAX_BDEV),
+BlueFS::BlueFS(CephContext* cct)
+  : cct(cct),
+    bdev(MAX_BDEV),
     ioc(MAX_BDEV),
     block_all(MAX_BDEV),
     block_total(MAX_BDEV, 0)
 
 void BlueFS::_init_logger()
 {
-  PerfCountersBuilder b(g_ceph_context, "BlueFS",
+  PerfCountersBuilder b(cct, "BlueFS",
                         l_bluefs_first, l_bluefs_last);
   b.add_u64_counter(l_bluefs_gift_bytes, "gift_bytes",
                    "Bytes gifted from BlueStore");
   b.add_u64_counter(l_bluefs_bytes_written_sst, "bytes_written_sst",
                    "Bytes written to SSTs");
   logger = b.create_perf_counters();
-  g_ceph_context->get_perfcounters_collection()->add(logger);
+  cct->get_perfcounters_collection()->add(logger);
 }
 
 void BlueFS::_shutdown_logger()
 {
-  g_ceph_context->get_perfcounters_collection()->remove(logger);
+  cct->get_perfcounters_collection()->remove(logger);
   delete logger;
 }
 
   dout(10) << __func__ << " bdev " << id << " path " << path << dendl;
   assert(id < bdev.size());
   assert(bdev[id] == NULL);
-  BlockDevice *b = BlockDevice::create(path, NULL, NULL);
+  BlockDevice *b = BlockDevice::create(cct, path, NULL, NULL);
   int r = b->open(path);
   if (r < 0) {
     delete b;
   dout(1) << __func__ << " bdev " << id << " path " << path
          << " size " << pretty_si_t(b->get_size()) << "B" << dendl;
   bdev[id] = b;
-  ioc[id] = new IOContext(NULL);
+  ioc[id] = new IOContext(cct, NULL);
   return 0;
 }
 
   assert(r == 0); // caller shouldn't ask for more than they can get
   int count = 0;
   uint64_t alloc_len = 0;;
-  AllocExtentVector extents = AllocExtentVector(want / g_conf->bluefs_alloc_size);
+  AllocExtentVector extents = AllocExtentVector(want / cct->_conf->bluefs_alloc_size);
 
-  r = alloc[id]->allocate(want, g_conf->bluefs_alloc_size, 0,
+  r = alloc[id]->allocate(want, cct->_conf->bluefs_alloc_size, 0,
                           &extents, &count, &alloc_len);
 
   *length = alloc_len;
   log_file->fnode.prefer_bdev = BDEV_WAL;
   int r = _allocate(
     log_file->fnode.prefer_bdev,
-    g_conf->bluefs_max_log_runway,
+    cct->_conf->bluefs_max_log_runway,
     &log_file->fnode.extents);
   assert(r == 0);
   log_writer = _create_writer(log_file);
       continue;
     }
     assert(bdev[id]->get_size());
-    alloc[id] = Allocator::create(g_conf->bluefs_allocator,
-                                  bdev[id]->get_size(),
-                                  g_conf->bluefs_alloc_size);
+    alloc[id] = Allocator::create(cct, cct->_conf->bluefs_allocator,
+                                 bdev[id]->get_size(),
+                                 cct->_conf->bluefs_alloc_size);
     interval_set<uint64_t>& p = block_all[id];
     for (interval_set<uint64_t>::iterator q = p.begin(); q != p.end(); ++q) {
       alloc[id]->init_add_free(q.get_start(), q.get_len());
   dout(10) << __func__ << " log_fnode " << super.log_fnode << dendl;
 
   FileReader *log_reader = new FileReader(
-    log_file, g_conf->bluefs_max_prefetch,
+    log_file, cct->_conf->bluefs_max_prefetch,
     false,  // !random
     true);  // ignore eof
   while (true) {
              << std::hex << x_off << "~" << l << std::dec
              << " of " << *p << dendl;
     int r = bdev[p->bdev]->read_random(p->offset + x_off, l, out,
-                                      g_conf->bluefs_buffered_io);
+                                      cct->_conf->bluefs_buffered_io);
     assert(r == 0);
     off += l;
     len -= l;
                << std::hex << x_off << "~" << l << std::dec
                << " of " << *p << dendl;
       int r = bdev[p->bdev]->read(p->offset + x_off, l, &buf->bl, ioc[p->bdev],
-                                 g_conf->bluefs_buffered_io);
+                                 cct->_conf->bluefs_buffered_io);
       assert(r == 0);
     }
     left = buf->get_buf_remaining(off);
 void BlueFS::compact_log()
 {
   std::unique_lock<std::mutex> l(lock);
-  if (g_conf->bluefs_compact_log_sync) {
+  if (cct->_conf->bluefs_compact_log_sync) {
      _compact_log_sync();
   } else {
     _compact_log_async(l);
           << (new_log ? " (async compaction in progress)" : "")
           << dendl;
   if (new_log ||
-      current < g_conf->bluefs_log_compact_min_size ||
-      ratio < g_conf->bluefs_log_compact_min_ratio) {
+      current < cct->_conf->bluefs_log_compact_min_size ||
+      ratio < cct->_conf->bluefs_log_compact_min_ratio) {
     return false;
   }
   return true;
   ::encode(t, bl);
   _pad_bl(bl);
 
-  uint64_t need = bl.length() + g_conf->bluefs_max_log_runway;
+  uint64_t need = bl.length() + cct->_conf->bluefs_max_log_runway;
   dout(20) << __func__ << " need " << need << dendl;
 
   mempool::bluefs::vector<bluefs_extent_t> old_extents;
 
   // 1. allocate new log space and jump to it.
   old_log_jump_to = log_file->fnode.get_allocated();
-  uint64_t need = old_log_jump_to + g_conf->bluefs_max_log_runway;
+  uint64_t need = old_log_jump_to + cct->_conf->bluefs_max_log_runway;
   dout(10) << __func__ << " old_log_jump_to 0x" << std::hex << old_log_jump_to
            << " need 0x" << need << std::dec << dendl;
   while (log_file->fnode.get_allocated() < need) {
     int r = _allocate(log_file->fnode.prefer_bdev,
-                     g_conf->bluefs_max_log_runway,
+                     cct->_conf->bluefs_max_log_runway,
                      &log_file->fnode.extents);
     assert(r == 0);
   }
 
   // conservative estimate for final encoded size
   new_log_jump_to = ROUND_UP_TO(t.op_bl.length() + super.block_size * 2,
-                                g_conf->bluefs_alloc_size);
+                                cct->_conf->bluefs_alloc_size);
   t.op_jump(log_seq, new_log_jump_to);
 
   bufferlist bl;
   // allocate some more space (before we run out)?
   int64_t runway = log_writer->file->fnode.get_allocated() -
     log_writer->get_effective_write_pos();
-  if (runway < (int64_t)g_conf->bluefs_min_log_runway) {
+  if (runway < (int64_t)cct->_conf->bluefs_min_log_runway) {
     dout(10) << __func__ << " allocating more log runway (0x"
             << std::hex << runway << std::dec  << " remaining)" << dendl;
     while (new_log_writer) {
       log_cond.wait(l);
     }
     int r = _allocate(log_writer->file->fnode.prefer_bdev,
-                     g_conf->bluefs_max_log_runway,
+                     cct->_conf->bluefs_max_log_runway,
                      &log_writer->file->fnode.extents);
     assert(r == 0);
     log_t.op_file_update(log_writer->file->fnode);
   if (h->file->fnode.ino == 1)
     buffered = false;
   else
-    buffered = g_conf->bluefs_buffered_io;
+    buffered = cct->_conf->bluefs_buffered_io;
 
   if (offset + length <= h->pos)
     return 0;
            << dendl;
       return r;
     }
-    if (g_conf->bluefs_preextend_wal_files &&
+    if (cct->_conf->bluefs_preextend_wal_files &&
        h->writer_type == WRITER_WAL) {
       // NOTE: this *requires* that rocksdb also has log recycling
       // enabled and is therefore doing robust CRCs on the log
   uint64_t length = h->buffer.length();
   uint64_t offset = h->pos;
   if (!force &&
-      length < g_conf->bluefs_min_flush_size) {
+      length < cct->_conf->bluefs_min_flush_size) {
     dout(10) << __func__ << " " << h << " ignoring, length " << length
-            << " < min_flush_size " << g_conf->bluefs_min_flush_size
+            << " < min_flush_size " << cct->_conf->bluefs_min_flush_size
             << dendl;
     return 0;
   }
   dout(10) << __func__ << " len 0x" << std::hex << len << std::dec
            << " from " << (int)id << dendl;
   assert(id < alloc.size());
-  uint64_t min_alloc_size = g_conf->bluefs_alloc_size;
+  uint64_t min_alloc_size = cct->_conf->bluefs_alloc_size;
 
   uint64_t left = ROUND_UP_TO(len, min_alloc_size);
   int r = -ENOSPC;
   }
 
   if (_should_compact_log()) {
-    if (g_conf->bluefs_compact_log_sync) {
+    if (cct->_conf->bluefs_compact_log_sync) {
       _compact_log_sync();
     } else {
       _compact_log_async(l);
   FileWriter *w = new FileWriter(f);
   for (unsigned i = 0; i < MAX_BDEV; ++i) {
     if (bdev[i]) {
-      w->iocv[i] = new IOContext(NULL);
+      w->iocv[i] = new IOContext(cct, NULL);
     } else {
       w->iocv[i] = NULL;
     }
   }
   File *file = q->second.get();
 
-  *h = new FileReader(file, random ? 4096 : g_conf->bluefs_max_prefetch,
+  *h = new FileReader(file, random ? 4096 : cct->_conf->bluefs_max_prefetch,
                      random, false);
   dout(10) << __func__ << " h " << *h << " on " << file->fnode << dendl;
   return 0;
 
 
 class BlueFS {
 public:
+  CephContext* cct;
   static constexpr unsigned MAX_BDEV = 3;
   static constexpr unsigned BDEV_WAL = 0;
   static constexpr unsigned BDEV_DB = 1;
   }
 
 public:
-  BlueFS();
+  BlueFS(CephContext* cct);
   ~BlueFS();
 
   // the super is always stored on bdev 0
 
     if (pattern == RANDOM)
       h->buf.max_prefetch = 4096;
     else if (pattern == SEQUENTIAL)
-      h->buf.max_prefetch = g_conf->bluefs_max_prefetch;
+      h->buf.max_prefetch = fs->cct->_conf->bluefs_max_prefetch;
   }
 
   // Remove any kind of caching of data from the offset to offset+length
 
 #include "BlueRocksEnv.h"
 #include "auth/Crypto.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluestore
 
 // bluestore_meta_onode
 
 static int get_key_object(const string& key, ghobject_t *oid);
 
-static void get_object_key(const ghobject_t& oid, string *key)
+static void get_object_key(CephContext* cct, const ghobject_t& oid,
+                          string *key)
 {
   key->clear();
 
 
 // Cache
 
-BlueStore::Cache *BlueStore::Cache::create(string type, PerfCounters *logger)
+BlueStore::Cache *BlueStore::Cache::create(CephContext* cct, string type,
+                                          PerfCounters *logger)
 {
   Cache *c = nullptr;
 
   if (type == "lru")
-    c = new LRUCache;
+    c = new LRUCache(cct);
   else if (type == "2q")
-    c = new TwoQCache;
+    c = new TwoQCache(cct);
   else
     assert(0 == "unrecognized cache type");
 
 
   // buffers
   if (buffer_bytes > buffer_max) {
-    uint64_t kin = buffer_max * g_conf->bluestore_2q_cache_kin_ratio;
+    uint64_t kin = buffer_max * cct->_conf->bluestore_2q_cache_kin_ratio;
     uint64_t khot = buffer_max - kin;
 
     // pre-calculate kout based on average buffer size too,
       uint64_t buffer_avg_size = buffer_bytes / buffer_num;
       assert(buffer_avg_size);
       uint64_t calculated_buffer_num = buffer_max / buffer_avg_size;
-      kout = calculated_buffer_num * g_conf->bluestore_2q_cache_kout_ratio;
+      kout = calculated_buffer_num * cct->_conf->bluestore_2q_cache_kout_ratio;
     }
 
     if (buffer_list_bytes[BUFFER_HOT] < khot) {
 void BlueStore::BufferSpace::_clear()
 {
   // note: we already hold cache->lock
-  dout(10) << __func__ << dendl;
+  ldout(cache->cct, 10) << __func__ << dendl;
   while (!buffer_map.empty()) {
     _rm_buffer(buffer_map.begin());
   }
 int BlueStore::BufferSpace::_discard(uint64_t offset, uint64_t length)
 {
   // note: we already hold cache->lock
-  dout(20) << __func__ << std::hex << " 0x" << offset << "~" << length
+  ldout(cache->cct, 20) << __func__ << std::hex << " 0x" << offset << "~" << length
            << std::dec << dendl;
   int cache_private = 0;
   cache->_audit("discard start");
     }
 
     Buffer *b = &*i;
-    dout(20) << __func__ << " " << *b << dendl;
+    ldout(cache->cct, 20) << __func__ << " " << *b << dendl;
     assert(b->is_writing());
 
     if (b->flags & Buffer::FLAG_NOCACHE) {
       break;
 
     if (p->second->offset < pos) {
-      dout(30) << __func__ << " cut " << *p->second << dendl;
+      ldout(cache->cct, 30) << __func__ << " cut " << *p->second << dendl;
       size_t left = pos - p->second->offset;
       size_t right = p->second->length - left;
       if (p->second->data.length()) {
     }
 
     assert(p->second->end() > pos);
-    dout(30) << __func__ << " move " << *p->second << dendl;
+    ldout(cache->cct, 30) << __func__ << " move " << *p->second << dendl;
     if (p->second->data.length()) {
       r._add_buffer(new Buffer(&r, p->second->state, p->second->seq,
                                p->second->offset - pos, p->second->data),
   std::lock_guard<std::recursive_mutex> l(cache->lock);
   auto p = onode_map.find(oid);
   if (p != onode_map.end()) {
-    dout(30) << __func__ << " " << oid << " " << o
-            << " raced, returning existing " << p->second << dendl;
+    ldout(cache->cct, 30) << __func__ << " " << oid << " " << o
+                         << " raced, returning existing " << p->second
+                         << dendl;
     return p->second;
   }
-  dout(30) << __func__ << " " << oid << " " << o << dendl;
+  ldout(cache->cct, 30) << __func__ << " " << oid << " " << o << dendl;
   onode_map[oid] = o;
   cache->_add_onode(o, 1);
   return o;
 BlueStore::OnodeRef BlueStore::OnodeSpace::lookup(const ghobject_t& oid)
 {
   std::lock_guard<std::recursive_mutex> l(cache->lock);
-  dout(30) << __func__ << dendl;
+  ldout(cache->cct, 30) << __func__ << dendl;
   ceph::unordered_map<ghobject_t,OnodeRef>::iterator p = onode_map.find(oid);
   if (p == onode_map.end()) {
-    dout(30) << __func__ << " " << oid << " miss" << dendl;
+    ldout(cache->cct, 30) << __func__ << " " << oid << " miss" << dendl;
     cache->logger->inc(l_bluestore_onode_misses);
     return OnodeRef();
   }
-  dout(30) << __func__ << " " << oid << " hit " << p->second << dendl;
+  ldout(cache->cct, 30) << __func__ << " " << oid << " hit " << p->second
+                       << dendl;
   cache->_touch_onode(p->second);
   cache->logger->inc(l_bluestore_onode_hits);
   return p->second;
 void BlueStore::OnodeSpace::clear()
 {
   std::lock_guard<std::recursive_mutex> l(cache->lock);
-  dout(10) << __func__ << dendl;
+  ldout(cache->cct, 10) << __func__ << dendl;
   for (auto &p : onode_map) {
     cache->_rm_onode(p.second);
   }
                                            uint32_t ps, int bits)
 {
   std::lock_guard<std::recursive_mutex> l(cache->lock);
-  dout(10) << __func__ << dendl;
+  ldout(cache->cct, 10) << __func__ << dendl;
 
   auto p = onode_map.begin();
   while (p != onode_map.end()) {
                                     const string& new_okey)
 {
   std::lock_guard<std::recursive_mutex> l(cache->lock);
-  dout(30) << __func__ << " " << old_oid << " -> " << new_oid << dendl;
+  ldout(cache->cct, 30) << __func__ << " " << old_oid << " -> " << new_oid
+                       << dendl;
   ceph::unordered_map<ghobject_t,OnodeRef>::iterator po, pn;
   po = onode_map.find(old_oid);
   pn = onode_map.find(new_oid);
 
   assert(po != onode_map.end());
   if (pn != onode_map.end()) {
-    dout(30) << __func__ << "  removing target " << pn->second << dendl;
+    ldout(cache->cct, 30) << __func__ << "  removing target " << pn->second
+                         << dendl;
     cache->_rm_onode(pn->second);
     onode_map.erase(pn);
   }
 bool BlueStore::OnodeSpace::map_any(std::function<bool(OnodeRef)> f)
 {
   std::lock_guard<std::recursive_mutex> l(cache->lock);
-  dout(20) << __func__ << dendl;
+  ldout(cache->cct, 20) << __func__ << dendl;
   for (auto& i : onode_map) {
     if (f(i.second)) {
       return true;
 void BlueStore::SharedBlob::put()
 {
   if (--nref == 0) {
-    dout(20) << __func__ << " " << this
-            << " removing self from set " << parent_set << dendl;
+    ldout(bc.cache->cct, 20) << __func__ << " " << this
+                              << " removing self from set " << parent_set
+                              << dendl;
     if (parent_set) {
       if (parent_set->remove(this)) {
        delete this;
       } else {
-       dout(20) << __func__ << " " << this
-                << " lost race to remove myself from set" << dendl;
+       ldout(bc.cache->cct, 20)
+         << __func__ << " " << this << " lost race to remove myself from set"
+         << dendl;
       }
     } else {
       delete this;
 #undef dout_prefix
 #define dout_prefix *_dout << "bluestore.extentmap(" << this << ") "
 
-BlueStore::ExtentMap::ExtentMap(Onode *o)
-  : onode(o),
-    inline_bl(g_conf->bluestore_extent_map_inline_shard_prealloc_size) {
+BlueStore::ExtentMap::ExtentMap(CephContext* cct, Onode *o)
+  : cct(cct), onode(o),
+    inline_bl(cct->_conf->bluestore_extent_map_inline_shard_prealloc_size) {
 }
 
 bool BlueStore::ExtentMap::update(KeyValueDB::Transaction t,
       bool never_happen = encode_some(0, OBJECT_MAX_SIZE, inline_bl, &n);
       assert(!never_happen);
       size_t len = inline_bl.length();
-      dout(20) << __func__ << " inline shard "
-              << len << " bytes from " << n << " extents" << dendl;
-      if (!force && len > g_conf->bluestore_extent_map_shard_max_size) {
+      dout(20) << __func__ << " inline shard " << len << " bytes from " << n<< " extents" << dendl;
+      if (!force && len > cct->_conf->bluestore_extent_map_shard_max_size) {
        return true;
       }
     }
          return true;
        }
         size_t len = bl.length();
+
        dout(20) << __func__ << " shard 0x" << std::hex
                 << p->offset << std::dec << " is " << len
                 << " bytes (was " << p->shard_info->bytes << ") from " << nn
                 << " extents" << dendl;
 
         //indicate need for reshard if force mode selected, len > shard_max size OR
-        //non-last shard size is below the min threshold. The last check is to avoid potential 
+        //non-last shard size is below the min threshold. The last check is to avoid potential
         //unneeded reshardings since this might happen permanently.
         if (!force &&
-             (len > g_conf->bluestore_extent_map_shard_max_size ||
+             (len > cct->_conf->bluestore_extent_map_shard_max_size ||
                (n != shards.end() && len < g_conf->bluestore_extent_map_shard_min_size))) {
           return true;
         }
       bytes += s.bytes;
     }
   }
-  unsigned target = g_conf->bluestore_extent_map_shard_target_size;
-  unsigned slop = target * g_conf->bluestore_extent_map_shard_target_size_slop;
+  unsigned target = cct->_conf->bluestore_extent_map_shard_target_size;
+  unsigned slop = target *
+    cct->_conf->bluestore_extent_map_shard_target_size_slop;
   unsigned extent_avg = bytes / extent_map.size();
-  dout(20) << __func__ << " extent_avg " << extent_avg
-          << " target " << target << " slop " << slop << dendl;
+  dout(20) << __func__ << " extent_avg " << extent_avg << " target " << target
+          << " slop " << slop << dendl;
 
   // reshard
   unsigned estimate = 0;
       offset = e.logical_offset;
       new_shard_info.emplace_back(bluestore_onode_t::shard_info());
       new_shard_info.back().offset = offset;
-      dout(20) << __func__ << "  new shard 0x" << std::hex << offset << std::dec
-              << dendl;
+      dout(20) << __func__ << "  new shard 0x" << std::hex << offset
+              << std::dec << dendl;
       estimate = 0;
     }
     estimate += extent_avg;
              if (b->get_blob().can_split_at(blob_offset) &&
                  blob_offset % min_alloc_size == 0) {
                dout(20) << __func__ << "    splitting blob, bstart 0x"
-                        << std::hex << bstart
-                        << " blob_offset 0x" << blob_offset
-                        << std::dec << " " << *b << dendl;
+                        << std::hex << bstart << " blob_offset 0x"
+                        << blob_offset << std::dec << " " << *b << dendl;
                b = split_blob(b, blob_offset, sh.offset);
                // switch b to the new right-hand side, in case it
                // *also* has to get split.
        le->assign_blob(blobs[blobid - 1]);
        assert(le->blob);
       } else {
-       Blob *b = new Blob();
+       Blob *b = new Blob(cct);
         uint64_t sbid = 0;
        b->decode(p, struct_v, &sbid, false);
        blobs[n] = b;
   unsigned n;
   denc_varint(n, p);
   while (n--) {
-    BlobRef b(new Blob());
+    BlobRef b(new Blob(c->store->cct));
     denc_varint(b->id, p);
     spanning_blob_map[b->id] = b;
     uint64_t sbid = 0;
     auto p = &shards[start];
     if (!p->loaded) {
       dout(20) << __func__ << " shard 0x" << std::hex << p->offset << std::dec
-               << " is not loaded, can't mark dirty" << dendl;
+              << " is not loaded, can't mark dirty" << dendl;
       assert(0 == "can't mark unloaded shard dirty");
     }
     if (!p->dirty) {
 {
   uint32_t end_pos = pos + lb->get_blob().get_logical_length() - blob_offset;
   dout(20) << __func__ << " 0x" << std::hex << pos << " end 0x" << end_pos
-          << " blob_offset 0x" << blob_offset << std::dec
-          << " " << *lb << dendl;
+          << " blob_offset 0x" << blob_offset << std::dec << " " << *lb
+          << dendl;
   BlobRef rb = onode->c->new_blob();
   lb->split(blob_offset, rb.get());
 
 void BlueStore::Onode::flush()
 {
   std::unique_lock<std::mutex> l(flush_lock);
-  dout(20) << __func__ << " " << flush_txns << dendl;
+  ldout(c->store->cct, 20) << __func__ << " " << flush_txns << dendl;
   while (!flush_txns.empty())
     flush_cond.wait(l);
-  dout(20) << __func__ << " done" << dendl;
+  ldout(c->store->cct, 20) << __func__ << " done" << dendl;
 }
 
 // =======================================================
 
   b->shared_blob = shared_blob_set.lookup(sbid);
   if (b->shared_blob) {
-    dout(10) << __func__ << " sbid 0x" << std::hex << sbid << std::dec
-            << " had " << *b->shared_blob << dendl;
+    ldout(store->cct, 10) << __func__ << " sbid 0x" << std::hex << sbid
+                         << std::dec << " had " << *b->shared_blob << dendl;
   } else {
     b->shared_blob = new SharedBlob(sbid, cache);
     shared_blob_set.add(b->shared_blob.get());
-    dout(10) << __func__ << " sbid 0x" << std::hex << sbid << std::dec
-            << " opened " << *b->shared_blob << dendl;
+    ldout(store->cct, 10) << __func__ << " sbid 0x" << std::hex << sbid
+                         << std::dec << " opened " << *b->shared_blob
+                         << dendl;
   }
 }
 
   get_shared_blob_key(sb->sbid, &key);
   int r = store->db->get(PREFIX_SHARED_BLOB, key, &v);
   if (r < 0) {
-    derr << __func__ << " sbid 0x" << std::hex << sb->sbid << std::dec
-        << " not found at key " << pretty_binary_string(key) << dendl;
+      lderr(store->cct) << __func__ << " sbid 0x" << std::hex << sb->sbid
+                       << std::dec << " not found at key "
+                       << pretty_binary_string(key) << dendl;
     assert(0 == "uh oh, missing shared_blob");
   }
 
   bufferlist::iterator p = v.begin();
   ::decode(sb->shared_blob, p);
-  dout(10) << __func__ << " sbid 0x" << std::hex << sb->sbid << std::dec
-          << " loaded shared_blob " << *sb << dendl;
+  ldout(store->cct, 10) << __func__ << " sbid 0x" << std::hex << sb->sbid
+                       << std::dec << " loaded shared_blob " << *sb << dendl;
   sb->loaded = true;
 }
 
 void BlueStore::Collection::make_blob_shared(uint64_t sbid, BlobRef b)
 {
-  dout(10) << __func__ << " " << *b << dendl;
+  ldout(store->cct, 10) << __func__ << " " << *b << dendl;
   bluestore_blob_t& blob = b->dirty_blob();
 
   // update blob
       b->shared_blob->shared_blob.ref_map.get(p.offset, p.length);
     }
   }
-  dout(20) << __func__ << " now " << *b << dendl;
+  ldout(store->cct, 20) << __func__ << " now " << *b << dendl;
 }
 
 BlueStore::OnodeRef BlueStore::Collection::get_onode(
   spg_t pgid;
   if (cid.is_pg(&pgid)) {
     if (!oid.match(cnode.bits, pgid.ps())) {
-      derr << __func__ << " oid " << oid << " not part of " << pgid
-          << " bits " << cnode.bits << dendl;
+      lderr(store->cct) << __func__ << " oid " << oid << " not part of "
+                       << pgid << " bits " << cnode.bits << dendl;
       ceph_abort();
     }
   }
     return o;
 
   string key;
-  get_object_key(oid, &key);
+  get_object_key(store->cct, oid, &key);
 
-  dout(20) << __func__ << " oid " << oid << " key "
-          << pretty_binary_string(key) << dendl;
+  ldout(store->cct, 20) << __func__ << " oid " << oid << " key "
+                       << pretty_binary_string(key) << dendl;
 
   bufferlist v;
   int r = store->db->get(PREFIX_OBJ, key, &v);
-  dout(20) << " r " << r << " v.len " << v.length() << dendl;
+  ldout(store->cct, 20) << " r " << r << " v.len " << v.length() << dendl;
   Onode *on;
   if (v.length() == 0) {
     assert(r == -ENOENT);
-    if (!g_conf->bluestore_debug_misc &&
+    if (!store->cct->_conf->bluestore_debug_misc &&
        !create)
       return OnodeRef();
 
   size_t seq;
   store->get_mempool_stats(&seq, &total_bytes, &total_onodes);
   if (seq == cache->last_trim_seq) {
-    dout(30) << __func__ << " no new mempool stats; nothing to do" << dendl;
+    ldout(store->cct, 30) << __func__ << " no new mempool stats; nothing to do"
+                         << dendl;
     return;
   }
   cache->last_trim_seq = seq;
   }
   float bytes_per_onode = (float)total_bytes / (float)total_onodes;
   size_t num_shards = store->cache_shards.size();
-  uint64_t shard_target = g_conf->bluestore_cache_size / num_shards;
-  dout(30) << __func__
-          << " total meta bytes " << total_bytes
-          << ", total onodes " << total_onodes
-          << ", bytes_per_onode " << bytes_per_onode
+  uint64_t shard_target = store->cct->_conf->bluestore_cache_size / num_shards;
+  ldout(store->cct, 30) << __func__
+                       << " total meta bytes " << total_bytes
+                       << ", total onodes " << total_onodes
+                       << ", bytes_per_onode " << bytes_per_onode
           << dendl;
-  cache->trim(shard_target, g_conf->bluestore_cache_meta_ratio, bytes_per_onode);
+  cache->trim(shard_target, store->cct->_conf->bluestore_cache_meta_ratio,
+             bytes_per_onode);
 
   store->_update_cache_logger();
 }
     store->mempool_onodes = mempool::bluestore_meta_onode::allocated_items();
     ++store->mempool_seq;
     utime_t wait;
-    wait += g_conf->bluestore_cache_trim_interval;
+    wait += store->cct->_conf->bluestore_cache_trim_interval;
     cond.WaitInterval(lock, wait);
   }
   stop = false;
     mempool_thread(this)
 {
   _init_logger();
-  g_ceph_context->_conf->add_observer(this);
+  cct->_conf->add_observer(this);
   set_cache_shards(1);
 
   if (cct->_conf->bluestore_shard_finishers) {
   }
   finishers.clear();
 
-  g_ceph_context->_conf->remove_observer(this);
+  cct->_conf->remove_observer(this);
   _shutdown_logger();
   assert(!mounted);
   assert(db == NULL);
 
 void BlueStore::_set_compression()
 {
-  comp_min_blob_size = g_conf->bluestore_compression_min_blob_size;
-  comp_max_blob_size = g_conf->bluestore_compression_max_blob_size;
+  comp_min_blob_size = cct->_conf->bluestore_compression_min_blob_size;
+  comp_max_blob_size = cct->_conf->bluestore_compression_max_blob_size;
 
-  auto m = Compressor::get_comp_mode_type(g_conf->bluestore_compression_mode);
+  auto m = Compressor::get_comp_mode_type(cct->_conf->bluestore_compression_mode);
   if (m) {
     comp_mode = *m;
   } else {
     derr << __func__ << " unrecognized value '"
-         << g_conf->bluestore_compression_mode
+         << cct->_conf->bluestore_compression_mode
          << "' for bluestore_compression_mode, reverting to 'none'"
          << dendl;
     comp_mode = Compressor::COMP_NONE;
 
   compressor = nullptr;
 
-  auto& alg_name = g_conf->bluestore_compression_algorithm;
+  auto& alg_name = cct->_conf->bluestore_compression_algorithm;
   if (!alg_name.empty()) {
     compressor = Compressor::create(cct, alg_name);
     if (!compressor) {
 void BlueStore::_set_csum()
 {
   csum_type = Checksummer::CSUM_NONE;
-  int t = Checksummer::get_csum_string_type(g_conf->bluestore_csum_type);
+  int t = Checksummer::get_csum_string_type(cct->_conf->bluestore_csum_type);
   if (t > Checksummer::CSUM_NONE)
     csum_type = t;
 
 
 void BlueStore::_init_logger()
 {
-  PerfCountersBuilder b(g_ceph_context, "BlueStore",
+  PerfCountersBuilder b(cct, "BlueStore",
                         l_bluestore_first, l_bluestore_last);
   b.add_time_avg(l_bluestore_state_prepare_lat, "state_prepare_lat",
     "Average prepare state latency");
   b.add_u64(l_bluestore_extent_compress, "bluestore_extent_compress",
             "Sum for extents that have been removed due to compression");
   logger = b.create_perf_counters();
-  g_ceph_context->get_perfcounters_collection()->add(logger);
+  cct->get_perfcounters_collection()->add(logger);
 }
 
 int BlueStore::_reload_logger()
 
 void BlueStore::_shutdown_logger()
 {
-  g_ceph_context->get_perfcounters_collection()->remove(logger);
+  cct->get_perfcounters_collection()->remove(logger);
   delete logger;
 }
 
-int BlueStore::get_block_device_fsid(const string& path, uuid_d *fsid)
+int BlueStore::get_block_device_fsid(CephContext* cct, const string& path,
+                                    uuid_d *fsid)
 {
   bluestore_bdev_label_t label;
-  int r = _read_bdev_label(path, &label);
+  int r = _read_bdev_label(cct, path, &label);
   if (r < 0)
     return r;
   *fsid = label.osd_uuid;
   return r;
 }
 
-int BlueStore::_read_bdev_label(string path, bluestore_bdev_label_t *label)
+int BlueStore::_read_bdev_label(CephContext* cct, string path,
+                               bluestore_bdev_label_t *label)
 {
   dout(10) << __func__ << dendl;
   int fd = ::open(path.c_str(), O_RDONLY);
     if (r < 0)
       return r;
   } else {
-    int r = _read_bdev_label(path, &label);
+    int r = _read_bdev_label(cct, path, &label);
     if (r < 0)
       return r;
     if (label.osd_uuid != fsid) {
   /*
    * Set device block size according to its media
    */
-  if (g_conf->bluestore_min_alloc_size) {
-    min_alloc_size = g_conf->bluestore_min_alloc_size;
+  if (cct->_conf->bluestore_min_alloc_size) {
+    min_alloc_size = cct->_conf->bluestore_min_alloc_size;
   } else {
     assert(bdev);
     if (bdev->is_rotational()) {
-      min_alloc_size = g_conf->bluestore_min_alloc_size_hdd;
+      min_alloc_size = cct->_conf->bluestore_min_alloc_size_hdd;
     } else {
-      min_alloc_size = g_conf->bluestore_min_alloc_size_ssd;
+      min_alloc_size = cct->_conf->bluestore_min_alloc_size_ssd;
     }
   }
   min_alloc_size_order = ctz(min_alloc_size);
   assert(min_alloc_size == 1u << min_alloc_size_order);
 
-  max_alloc_size = g_conf->bluestore_max_alloc_size;
+  max_alloc_size = cct->_conf->bluestore_max_alloc_size;
 
   dout(10) << __func__ << " min_alloc_size 0x" << std::hex << min_alloc_size
           << std::dec << " order " << min_alloc_size_order
   bluestore_bdev_label_t label;
   assert(bdev == NULL);
   string p = path + "/block";
-  bdev = BlockDevice::create(p, aio_cb, static_cast<void*>(this));
+  bdev = BlockDevice::create(cct, p, aio_cb, static_cast<void*>(this));
   int r = bdev->open(p);
   if (r < 0)
     goto fail;
 int BlueStore::_open_fm(bool create)
 {
   assert(fm == NULL);
-  fm = FreelistManager::create(freelist_type, db, PREFIX_ALLOC);
+  fm = FreelistManager::create(cct, freelist_type, db, PREFIX_ALLOC);
 
   if (create) {
     // initialize freespace
     fm->create(bdev->get_size(), t);
 
     uint64_t reserved = 0;
-    if (g_conf->bluestore_bluefs) {
+    if (cct->_conf->bluestore_bluefs) {
       assert(bluefs_extents.num_intervals() == 1);
       interval_set<uint64_t>::iterator p = bluefs_extents.begin();
       reserved = p.get_start() + p.get_len();
     // instead rely on bluefs_extents.
     fm->allocate(0, BLUEFS_START, t);
 
-    if (g_conf->bluestore_debug_prefill > 0) {
+    if (cct->_conf->bluestore_debug_prefill > 0) {
       uint64_t end = bdev->get_size() - reserved;
       dout(1) << __func__ << " pre-fragmenting freespace, using "
-             << g_conf->bluestore_debug_prefill << " with max free extent "
-             << g_conf->bluestore_debug_prefragment_max << dendl;
+             << cct->_conf->bluestore_debug_prefill << " with max free extent "
+             << cct->_conf->bluestore_debug_prefragment_max << dendl;
       uint64_t start = P2ROUNDUP(reserved, min_alloc_size);
-      uint64_t max_b = g_conf->bluestore_debug_prefragment_max / min_alloc_size;
-      float r = g_conf->bluestore_debug_prefill;
+      uint64_t max_b = cct->_conf->bluestore_debug_prefragment_max / min_alloc_size;
+      float r = cct->_conf->bluestore_debug_prefill;
       r /= 1.0 - r;
       bool stop = false;
 
 {
   assert(alloc == NULL);
   assert(bdev->get_size());
-  alloc = Allocator::create(g_conf->bluestore_allocator,
+  alloc = Allocator::create(cct, cct->_conf->bluestore_allocator,
                             bdev->get_size(),
                             min_min_alloc_size);
   uint64_t num = 0, bytes = 0;
 
   string kv_backend;
   if (create) {
-    kv_backend = g_conf->bluestore_kvbackend;
+    kv_backend = cct->_conf->bluestore_kvbackend;
   } else {
     r = read_meta("kv_backend", &kv_backend);
     if (r < 0) {
 
   bool do_bluefs;
   if (create) {
-    do_bluefs = g_conf->bluestore_bluefs;
+    do_bluefs = cct->_conf->bluestore_bluefs;
   } else {
     string s;
     r = read_meta("bluefs", &s);
       derr << " backend must be rocksdb to use bluefs" << dendl;
       return -EINVAL;
     }
-    bluefs = new BlueFS;
+    bluefs = new BlueFS(cct);
 
     string bfn;
     struct stat st;
       // note: we might waste a 4k block here if block.db is used, but it's
       // simpler.
       uint64_t initial =
-       bdev->get_size() * (g_conf->bluestore_bluefs_min_ratio +
-                           g_conf->bluestore_bluefs_gift_ratio);
-      initial = MAX(initial, g_conf->bluestore_bluefs_min);
+       bdev->get_size() * (cct->_conf->bluestore_bluefs_min_ratio +
+                           cct->_conf->bluestore_bluefs_gift_ratio);
+      initial = MAX(initial, cct->_conf->bluestore_bluefs_min);
       // align to bluefs's alloc_size
-      initial = P2ROUNDUP(initial, g_conf->bluefs_alloc_size);
-      initial += g_conf->bluefs_alloc_size - BLUEFS_START;
+      initial = P2ROUNDUP(initial, cct->_conf->bluefs_alloc_size);
+      initial += cct->_conf->bluefs_alloc_size - BLUEFS_START;
       bluefs->add_block_extent(bluefs_shared_bdev, BLUEFS_START, initial);
       bluefs_extents.insert(BLUEFS_START, initial);
     }
          bluefs->get_block_device_size(BlueFS::BDEV_WAL) -
           BDEV_LABEL_BLOCK_SIZE);
       }
-      g_conf->set_val("rocksdb_separate_wal_dir", "true");
+      cct->_conf->set_val("rocksdb_separate_wal_dir", "true");
     } else {
-      g_conf->set_val("rocksdb_separate_wal_dir", "false");
+      cct->_conf->set_val("rocksdb_separate_wal_dir", "false");
     }
 
     if (create) {
       derr << __func__ << " failed bluefs mount: " << cpp_strerror(r) << dendl;
       goto free_bluefs;
     }
-    if (g_conf->bluestore_bluefs_env_mirror) {
+    if (cct->_conf->bluestore_bluefs_env_mirror) {
       rocksdb::Env *a = new BlueRocksEnv(bluefs);
       unique_ptr<rocksdb::Directory> dir;
       rocksdb::Env *b = rocksdb::Env::Default();
                << (uint64_t)(db_size * 95 / 100) << " "
                << fn + ".slow" << ","
                << (uint64_t)(slow_size * 95 / 100);
-      g_conf->set_val("rocksdb_db_paths", db_paths.str(), false, false);
+      cct->_conf->set_val("rocksdb_db_paths", db_paths.str(), false, false);
       dout(10) << __func__ << " set rocksdb_db_paths to "
-              << g_conf->rocksdb_db_paths << dendl;
+              << cct->_conf->rocksdb_db_paths << dendl;
     }
 
     if (create) {
       env->CreateDir(fn);
-      if (g_conf->rocksdb_separate_wal_dir)
+      if (cct->_conf->rocksdb_separate_wal_dir)
        env->CreateDir(fn + ".wal");
-      if (g_conf->rocksdb_db_paths.length())
+      if (cct->_conf->rocksdb_db_paths.length())
        env->CreateDir(fn + ".slow");
     }
   } else if (create) {
     }
 
     // wal_dir, too!
-    if (g_conf->rocksdb_separate_wal_dir) {
+    if (cct->_conf->rocksdb_separate_wal_dir) {
       string walfn = path + "/db.wal";
       r = ::mkdir(walfn.c_str(), 0755);
       if (r < 0)
     }
   }
 
-  db = KeyValueDB::create(g_ceph_context,
+  db = KeyValueDB::create(cct,
                          kv_backend,
                          fn,
                          static_cast<void*>(env));
   db->set_merge_operator(PREFIX_STAT, merge_op);
 
   if (kv_backend == "rocksdb")
-    options = g_conf->bluestore_rocksdb_options;
+    options = cct->_conf->bluestore_rocksdb_options;
   db->init(options);
   if (create)
     r = db->create_and_open(err);
 
   uint64_t gift = 0;
   uint64_t reclaim = 0;
-  if (bluefs_ratio < g_conf->bluestore_bluefs_min_ratio) {
-    gift = g_conf->bluestore_bluefs_gift_ratio * total_free;
+  if (bluefs_ratio < cct->_conf->bluestore_bluefs_min_ratio) {
+    gift = cct->_conf->bluestore_bluefs_gift_ratio * total_free;
     dout(10) << __func__ << " bluefs_ratio " << bluefs_ratio
-            << " < min_ratio " << g_conf->bluestore_bluefs_min_ratio
+            << " < min_ratio " << cct->_conf->bluestore_bluefs_min_ratio
             << ", should gift " << pretty_si_t(gift) << dendl;
-  } else if (bluefs_ratio > g_conf->bluestore_bluefs_max_ratio) {
-    reclaim = g_conf->bluestore_bluefs_reclaim_ratio * total_free;
-    if (bluefs_total - reclaim < g_conf->bluestore_bluefs_min)
-      reclaim = bluefs_total - g_conf->bluestore_bluefs_min;
+  } else if (bluefs_ratio > cct->_conf->bluestore_bluefs_max_ratio) {
+    reclaim = cct->_conf->bluestore_bluefs_reclaim_ratio * total_free;
+    if (bluefs_total - reclaim < cct->_conf->bluestore_bluefs_min)
+      reclaim = bluefs_total - cct->_conf->bluestore_bluefs_min;
     dout(10) << __func__ << " bluefs_ratio " << bluefs_ratio
-            << " > max_ratio " << g_conf->bluestore_bluefs_max_ratio
+            << " > max_ratio " << cct->_conf->bluestore_bluefs_max_ratio
             << ", should reclaim " << pretty_si_t(reclaim) << dendl;
   }
-  if (bluefs_total < g_conf->bluestore_bluefs_min &&
-    g_conf->bluestore_bluefs_min <
-      (uint64_t)(g_conf->bluestore_bluefs_max_ratio * total_free)) {
-    uint64_t g = g_conf->bluestore_bluefs_min - bluefs_total;
+  if (bluefs_total < cct->_conf->bluestore_bluefs_min &&
+    cct->_conf->bluestore_bluefs_min <
+      (uint64_t)(cct->_conf->bluestore_bluefs_max_ratio * total_free)) {
+    uint64_t g = cct->_conf->bluestore_bluefs_min - bluefs_total;
     dout(10) << __func__ << " bluefs_total " << bluefs_total
-            << " < min " << g_conf->bluestore_bluefs_min
+            << " < min " << cct->_conf->bluestore_bluefs_min
             << ", should gift " << pretty_si_t(g) << dendl;
     if (g > gift)
       gift = g;
     int count = 0;
     uint64_t alloc_len = 0;
     AllocExtentVector exts = AllocExtentVector(gift / min_alloc_size);
-    r = alloc->allocate(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count, &alloc_len);
+    r = alloc->allocate(gift, cct->_conf->bluefs_alloc_size, 0, 0, &exts, &count, &alloc_len);
 
     if (r < 0 || alloc_len < gift) {
       derr << __func__ << " allocate failed on 0x" << std::hex << gift
          return r;
        }
 
-       if (g_conf->bluestore_block_preallocate_file) {
+       if (cct->_conf->bluestore_block_preallocate_file) {
 #ifdef HAVE_POSIX_FALLOCATE
          r = ::posix_fallocate(fd, 0, size);
          if (r) {
     r = read_meta("mkfs_done", &done);
     if (r == 0) {
       dout(1) << __func__ << " already created" << dendl;
-      if (g_conf->bluestore_fsck_on_mkfs) {
-        r = fsck(g_conf->bluestore_fsck_on_mkfs_deep);
+      if (cct->_conf->bluestore_fsck_on_mkfs) {
+        r = fsck(cct->_conf->bluestore_fsck_on_mkfs_deep);
         if (r < 0) {
           derr << __func__ << " fsck found fatal error: " << cpp_strerror(r)
                << dendl;
     }
   }
 
-  freelist_type = g_conf->bluestore_freelist_type;
+  freelist_type = cct->_conf->bluestore_freelist_type;
 
   r = _open_path();
   if (r < 0)
     fsid = old_fsid;
   }
 
-  r = _setup_block_symlink_or_file("block", g_conf->bluestore_block_path,
-                                  g_conf->bluestore_block_size,
-                                  g_conf->bluestore_block_create);
+  r = _setup_block_symlink_or_file("block", cct->_conf->bluestore_block_path,
+                                  cct->_conf->bluestore_block_size,
+                                  cct->_conf->bluestore_block_create);
   if (r < 0)
     goto out_close_fsid;
-  if (g_conf->bluestore_bluefs) {
-    r = _setup_block_symlink_or_file("block.wal", g_conf->bluestore_block_wal_path,
-       g_conf->bluestore_block_wal_size,
-       g_conf->bluestore_block_wal_create);
+  if (cct->_conf->bluestore_bluefs) {
+    r = _setup_block_symlink_or_file("block.wal", cct->_conf->bluestore_block_wal_path,
+       cct->_conf->bluestore_block_wal_size,
+       cct->_conf->bluestore_block_wal_create);
     if (r < 0)
       goto out_close_fsid;
-    r = _setup_block_symlink_or_file("block.db", g_conf->bluestore_block_db_path,
-       g_conf->bluestore_block_db_size,
-       g_conf->bluestore_block_db_create);
+    r = _setup_block_symlink_or_file("block.db", cct->_conf->bluestore_block_db_path,
+       cct->_conf->bluestore_block_db_size,
+       cct->_conf->bluestore_block_db_create);
     if (r < 0)
       goto out_close_fsid;
   }
   if (r < 0)
     goto out_close_fm;
 
-  r = write_meta("kv_backend", g_conf->bluestore_kvbackend);
+  r = write_meta("kv_backend", cct->_conf->bluestore_kvbackend);
   if (r < 0)
     goto out_close_alloc;
-  r = write_meta("bluefs", stringify((int)g_conf->bluestore_bluefs));
+  r = write_meta("bluefs", stringify((int)cct->_conf->bluestore_bluefs));
   if (r < 0)
     goto out_close_alloc;
 
   _close_path();
 
   if (r == 0 &&
-      g_conf->bluestore_fsck_on_mkfs) {
-    int rc = fsck(g_conf->bluestore_fsck_on_mkfs_deep);
+      cct->_conf->bluestore_fsck_on_mkfs) {
+    int rc = fsck(cct->_conf->bluestore_fsck_on_mkfs_deep);
     if (rc < 0)
       return rc;
     if (rc > 0) {
   assert(num >= old);
   cache_shards.resize(num);
   for (unsigned i = old; i < num; ++i) {
-    cache_shards[i] = Cache::create(g_conf->bluestore_cache_type, logger);
+    cache_shards[i] = Cache::create(cct, cct->_conf->bluestore_cache_type,
+                                   logger);
   }
 }
 
     }
   }
 
-  if (g_conf->bluestore_fsck_on_mount) {
-    int rc = fsck(g_conf->bluestore_fsck_on_mount_deep);
+  if (cct->_conf->bluestore_fsck_on_mount) {
+    int rc = fsck(cct->_conf->bluestore_fsck_on_mount_deep);
     if (rc < 0)
       return rc;
     if (rc > 0) {
   _close_fsid();
   _close_path();
 
-  if (g_conf->bluestore_fsck_on_umount) {
-    int rc = fsck(g_conf->bluestore_fsck_on_umount_deep);
+  if (cct->_conf->bluestore_fsck_on_umount) {
+    int rc = fsck(cct->_conf->bluestore_fsck_on_umount_deep);
     if (rc < 0)
       return rc;
     if (rc > 0) {
   if (op_flags & CEPH_OSD_OP_FLAG_FADVISE_WILLNEED) {
     dout(20) << __func__ << " will do buffered read" << dendl;
     buffered = true;
-  } else if (g_conf->bluestore_default_buffered_read &&
+  } else if (cct->_conf->bluestore_default_buffered_read &&
             (op_flags & (CEPH_OSD_OP_FLAG_FADVISE_DONTNEED |
                          CEPH_OSD_OP_FLAG_FADVISE_NOCACHE)) == 0) {
     dout(20) << __func__ << " defaulting to buffered read" << dendl;
             << " need 0x" << b2r_it->second << std::dec << dendl;
     if (bptr->get_blob().has_flag(bluestore_blob_t::FLAG_COMPRESSED)) {
       bufferlist compressed_bl, raw_bl;
-      IOContext ioc(NULL);   // FIXME?
+      IOContext ioc(cct, NULL);   // FIXME?
       r = bptr->get_blob().map(
        0, bptr->get_blob().get_ondisk_length(),
        [&](uint64_t offset, uint64_t length) {
                 << dendl;
 
        // read it
-       IOContext ioc(NULL);  // FIXME?
+       IOContext ioc(cct, NULL);  // FIXME?
        bufferlist bl;
        r = bptr->get_blob().map(r_off, r_len,
                             [&](uint64_t offset, uint64_t length) {
     temp = true;
   } else {
     string k;
-    get_object_key(start, &k);
+    get_object_key(cct, start, &k);
     if (start.hobj.is_temp()) {
       temp = true;
       assert(k >= temp_start_key && k < temp_end_key);
   if (end.hobj.is_max()) {
     pend = temp ? temp_end_key : end_key;
   } else {
-    get_object_key(end, &end_key);
+    get_object_key(cct, end, &end_key);
     if (end.hobj.is_temp()) {
       if (temp)
        pend = end_key;
 
 BlueStore::TransContext *BlueStore::_txc_create(OpSequencer *osr)
 {
-  TransContext *txc = new TransContext(osr);
+  TransContext *txc = new TransContext(cct, osr);
   txc->t = db->get_transaction();
   osr->queue_new(txc);
   dout(20) << __func__ << " osr " << osr << " = " << txc
         sb->bc.finish_write(txc->seq);
       }
       txc->shared_blobs_written.clear();
-      if (g_conf->bluestore_sync_submit_transaction &&
+      if (cct->_conf->bluestore_sync_submit_transaction &&
          fm->supports_parallel_transactions()) {
        if (txc->last_nid >= nid_max ||
            txc->last_blobid >= blobid_max) {
        } else if (txc->osr->txc_with_unstable_io) {
          dout(20) << __func__ << " prior txc(s) with unstable ios "
                   << txc->osr->txc_with_unstable_io.load() << dendl;
-       } else if (g_conf->bluestore_debug_randomize_serial_transaction &&
-                  rand() % g_conf->bluestore_debug_randomize_serial_transaction
+       } else if (cct->_conf->bluestore_debug_randomize_serial_transaction &&
+                  rand() % cct->_conf->bluestore_debug_randomize_serial_transaction
                   == 0) {
          dout(20) << __func__ << " DEBUG randomly forcing submit via kv thread"
                   << dendl;
 void BlueStore::_txc_release_alloc(TransContext *txc)
 {
   // update allocator with full released set
-  if (!g_conf->bluestore_debug_no_reuse_blocks) {
+  if (!cct->_conf->bluestore_debug_no_reuse_blocks) {
     for (interval_set<uint64_t>::iterator p = txc->released.begin();
         p != txc->released.end();
         ++p) {
       // it.  in either case, we increase the max in the earlier txn
       // we submit.
       uint64_t new_nid_max = 0, new_blobid_max = 0;
-      if (nid_last + g_conf->bluestore_nid_prealloc/2 > nid_max) {
+      if (nid_last + cct->_conf->bluestore_nid_prealloc/2 > nid_max) {
        KeyValueDB::Transaction t =
          kv_submitting.empty() ? synct : kv_submitting.front()->t;
-       new_nid_max = nid_last + g_conf->bluestore_nid_prealloc;
+       new_nid_max = nid_last + cct->_conf->bluestore_nid_prealloc;
        bufferlist bl;
        ::encode(new_nid_max, bl);
        t->set(PREFIX_SUPER, "nid_max", bl);
        dout(10) << __func__ << " new_nid_max " << new_nid_max << dendl;
       }
-      if (blobid_last + g_conf->bluestore_blobid_prealloc/2 > blobid_max) {
+      if (blobid_last + cct->_conf->bluestore_blobid_prealloc/2 > blobid_max) {
        KeyValueDB::Transaction t =
          kv_submitting.empty() ? synct : kv_submitting.front()->t;
-       new_blobid_max = blobid_last + g_conf->bluestore_blobid_prealloc;
+       new_blobid_max = blobid_last + cct->_conf->bluestore_blobid_prealloc;
        bufferlist bl;
        ::encode(new_blobid_max, bl);
        t->set(PREFIX_SUPER, "blobid_max", bl);
   txc->log_state_latency(logger, l_bluestore_state_wal_queued_lat);
   txc->state = TransContext::STATE_WAL_APPLYING;
 
-  if (g_conf->bluestore_inject_wal_apply_delay) {
+  if (cct->_conf->bluestore_inject_wal_apply_delay) {
     dout(20) << __func__ << " bluestore_inject_wal_apply_delay "
-            << g_conf->bluestore_inject_wal_apply_delay
+            << cct->_conf->bluestore_inject_wal_apply_delay
             << dendl;
     utime_t t;
-    t.set_from_double(g_conf->bluestore_inject_wal_apply_delay);
+    t.set_from_double(cct->_conf->bluestore_inject_wal_apply_delay);
     t.sleep();
     dout(20) << __func__ << " finished sleep" << dendl;
   }
   ObjectStore::Transaction::collect_contexts(
     tls, &onreadable, &ondisk, &onreadable_sync);
 
-  if (g_conf->objectstore_blackhole) {
+  if (cct->_conf->objectstore_blackhole) {
     dout(0) << __func__ << " objectstore_blackhole = TRUE, dropping transaction"
            << dendl;
     delete ondisk;
 
 void BlueStore::_dump_onode(OnodeRef o, int log_level)
 {
-  if (!g_conf->subsys.should_gather(ceph_subsys_bluestore, log_level))
+  if (!cct->_conf->subsys.should_gather(ceph_subsys_bluestore, log_level))
     return;
   dout(log_level) << __func__ << " " << o << " " << o->oid
                  << " nid " << o->onode.nid
 
   auto crr = select_option(
     "compression_required_ratio",
-    g_conf->bluestore_compression_required_ratio,
+    cct->_conf->bluestore_compression_required_ratio,
     [&]() {
       double val;
       if(coll->pool_opts.get(pool_opts_t::COMPRESSION_REQUIRED_RATIO, &val)) {
   if (fadvise_flags & CEPH_OSD_OP_FLAG_FADVISE_WILLNEED) {
     dout(20) << __func__ << " will do buffered write" << dendl;
     wctx.buffered = true;
-  } else if (g_conf->bluestore_default_buffered_write &&
+  } else if (cct->_conf->bluestore_default_buffered_write &&
             (fadvise_flags & (CEPH_OSD_OP_FLAG_FADVISE_DONTNEED |
                               CEPH_OSD_OP_FLAG_FADVISE_NOCACHE)) == 0) {
     dout(20) << __func__ << " defaulting to buffered write" << dendl;
     }
   }
   if (wctx.target_blob_size == 0 ||
-      wctx.target_blob_size > g_conf->bluestore_max_blob_size) {
-    wctx.target_blob_size = g_conf->bluestore_max_blob_size;
+      wctx.target_blob_size > cct->_conf->bluestore_max_blob_size) {
+    wctx.target_blob_size = cct->_conf->bluestore_max_blob_size;
   }
   // set the min blob size floor at 2x the min_alloc_size, or else we
   // won't be able to allocate a smaller extent for the compressed
   r = _do_truncate(txc, c, newo, 0);
   if (r < 0)
     goto out;
-  if (g_conf->bluestore_clone_cow) {
+  if (cct->_conf->bluestore_clone_cow) {
     _do_clone_range(txc, c, oldo, newo, 0, oldo->onode.size, 0);
   } else {
     bufferlist bl;
       } else if (!e.blob->shared_blob->loaded) {
        c->load_shared_blob(e.blob->shared_blob);
       }
-      cb = new Blob;
+      cb = new Blob(cct);
       e.blob->last_encoded_id = n;
       id_to_blob[n] = cb;
       e.blob->dup(*cb);
   _assign_nid(txc, newo);
 
   if (length > 0) {
-    if (g_conf->bluestore_clone_cow) {
+    if (cct->_conf->bluestore_clone_cow) {
       _do_zero(txc, c, newo, dstoff, length);
       _do_clone_range(txc, c, oldo, newo, srcoff, length, dstoff);
     } else {
 
   // rewrite shards
   oldo->extent_map.fault_range(db, 0, oldo->onode.size);
-  get_object_key(new_oid, &new_okey);
+  get_object_key(cct, new_oid, &new_okey);
   for (auto &s : oldo->extent_map.shards) {
     txc->t->rmkey(PREFIX_OBJ, s.key);
     get_extent_shard_key(new_okey, s.offset, &s.key);
 
   // -----------------------------------------------------
   // types
 public:
-
   // config observer
   virtual const char** get_tracked_conf_keys() const override;
   virtual void handle_conf_change(const struct md_config_t *conf,
   /// in-memory blob metadata and associated cached buffers (if any)
   struct Blob {
     MEMPOOL_CLASS_HELPERS();
+    CephContext* cct;
 
     std::atomic_int nref = {0};     ///< reference count
     int16_t id = -1;                ///< id, for spanning blobs only, >= 0
     bluestore_extent_ref_map_t ref_map;
 
   public:
-    Blob() {}
+    Blob(CephContext* cct) : cct(cct) {}
     ~Blob() {
     }
 
 
   /// a sharded extent map, mapping offsets to lextents to blobs
   struct ExtentMap {
+    CephContext* cct;
     Onode *onode;
     extent_map_t extent_map;        ///< map of Extents to Blobs
     blob_map_t spanning_blob_map;   ///< blobs that span shards
       void operator()(Extent *e) { delete e; }
     };
 
-    ExtentMap(Onode *o);
+    ExtentMap(CephContext* cct, Onode *o);
     ~ExtentMap() {
       extent_map.clear_and_dispose(DeleteDisposer());
     }
        oid(o),
        key(k),
        exists(false),
-       extent_map(this) {
+       extent_map(c->store->cct, this) {
     }
 
     void flush();
 
   /// a cache (shard) of onodes and buffers
   struct Cache {
+    CephContext* cct;
     PerfCounters *logger;
     std::recursive_mutex lock;          ///< protect lru and other structures
 
 
     size_t last_trim_seq = 0;
 
-    static Cache *create(string type, PerfCounters *logger);
+    static Cache *create(CephContext* cct, string type, PerfCounters *logger);
 
+    Cache(CephContext* cct) : cct(cct) {}
     virtual ~Cache() {}
 
     virtual void _add_onode(OnodeRef& o, int level) = 0;
     uint64_t buffer_size = 0;
 
   public:
+    LRUCache(CephContext* cct) : Cache(cct) {}
     uint64_t _get_num_onodes() override {
       return onode_lru.size();
     }
     uint64_t buffer_list_bytes[BUFFER_TYPE_MAX] = {0}; ///< bytes per type
 
   public:
+    TwoQCache(CephContext* cct) : Cache(cct) {}
     uint64_t _get_num_onodes() override {
       return onode_lru.size();
     }
     void make_blob_shared(uint64_t sbid, BlobRef b);
 
     BlobRef new_blob() {
-      BlobRef b = new Blob;
+      BlobRef b = new Blob(store->cct);
       b->shared_blob = new SharedBlob(cache);
       return b;
     }
     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(OpSequencer *o)
+    explicit TransContext(CephContext* cct, OpSequencer *o)
       : state(STATE_PREPARE),
        osr(o),
        ops(0),
        onreadable(NULL),
        onreadable_sync(NULL),
        wal_txn(NULL),
-       ioc(this),
+       ioc(cct, this),
        start(ceph_clock_now()) {
         last_stamp = start;
     }
                                   bool create);
 
   int _write_bdev_label(string path, bluestore_bdev_label_t label);
-  static int _read_bdev_label(string path, bluestore_bdev_label_t *label);
+  static int _read_bdev_label(CephContext* cct, string path,
+                             bluestore_bdev_label_t *label);
   int _check_or_set_bdev_label(string path, uint64_t size, string desc,
                               bool create);
 
   bool wants_journal() override { return false; };
   bool allows_journal() override { return false; };
 
-  static int get_block_device_fsid(const string& path, uuid_d *fsid);
+  static int get_block_device_fsid(CephContext* cct, const string& path,
+                                  uuid_d *fsid);
 
   bool test_mount_in_use() override;
 
   }
 private:
   bool _debug_data_eio(const ghobject_t& o) {
-    if (!g_conf->bluestore_debug_inject_read_err) {
+    if (!cct->_conf->bluestore_debug_inject_read_err) {
       return false;
     }
     RWLock::RLocker l(debug_read_error_lock);
     return debug_data_error_objects.count(o);
   }
   bool _debug_mdata_eio(const ghobject_t& o) {
-    if (!g_conf->bluestore_debug_inject_read_err) {
+    if (!cct->_conf->bluestore_debug_inject_read_err) {
       return false;
     }
     RWLock::RLocker l(debug_read_error_lock);
     return debug_mdata_error_objects.count(o);
   }
   void _debug_obj_on_delete(const ghobject_t& o) {
-    if (g_conf->bluestore_debug_inject_read_err) {
+    if (cct->_conf->bluestore_debug_inject_read_err) {
       RWLock::WLocker l(debug_read_error_lock);
       debug_data_error_objects.erase(o);
       debug_mdata_error_objects.erase(o);
 
 
 #include "common/debug.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluestore
 #undef dout_prefix
 #define dout_prefix *_dout << "freelist "
       p->second = newlen;
     }
   }
-  if (g_conf->bluestore_debug_freelist)
+  if (cct->_conf->bluestore_debug_freelist)
     _audit();
 }
 
 
   kv_free[offset] = length;
 
-  if (g_conf->bluestore_debug_freelist)
+  if (cct->_conf->bluestore_debug_freelist)
     _audit();
 }
 
   void _dump();
 
 public:
-  ExtentFreelistManager(KeyValueDB *kvdb, std::string prefix) :
+  ExtentFreelistManager(CephContext* cct, KeyValueDB *kvdb,
+                       std::string prefix) :
+    FreelistManager(cct),
     kvdb(kvdb),
     prefix(prefix),
     total_free(0) {
 
 #include "BitmapFreelistManager.h"
 
 FreelistManager *FreelistManager::create(
+  CephContext* cct,
   string type,
   KeyValueDB *kvdb,
   string prefix)
   // freelist type until after we open the db.
   assert(prefix == "B");
   if (type == "extent")
-    return new ExtentFreelistManager(kvdb, "B");
+    return new ExtentFreelistManager(cct, kvdb, "B");
   if (type == "bitmap")
-    return new BitmapFreelistManager(kvdb, "B", "b");
+    return new BitmapFreelistManager(cct, kvdb, "B", "b");
   return NULL;
 }
 
 
 
 class FreelistManager {
 public:
-  FreelistManager() {}
+  CephContext* cct;
+  FreelistManager(CephContext* cct) : cct(cct) {}
   virtual ~FreelistManager() {}
 
   static FreelistManager *create(
+    CephContext* cct,
     string type,
     KeyValueDB *db,
     string prefix);
 
 #include "common/blkdev.h"
 #include "common/align.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bdev
 #undef dout_prefix
 #define dout_prefix *_dout << "bdev(" << path << ") "
 
-KernelDevice::KernelDevice(aio_callback_t cb, void *cbpriv)
-  : fd_direct(-1),
+KernelDevice::KernelDevice(CephContext* cct, aio_callback_t cb, void *cbpriv)
+  : BlockDevice(cct),
+    fd_direct(-1),
     fd_buffered(-1),
     size(0), block_size(0),
     fs(NULL), aio(false), dio(false),
     debug_lock("KernelDevice::debug_lock"),
     flush_lock("KernelDevice::flush_lock"),
-    aio_queue(g_conf->bdev_aio_max_queue_depth),
+    aio_queue(cct->_conf->bdev_aio_max_queue_depth),
     aio_callback(cb),
     aio_callback_priv(cbpriv),
     aio_stop(false),
     goto out_direct;
   }
   dio = true;
-  aio = g_conf->bdev_aio;
+  aio = cct->_conf->bdev_aio;
   if (!aio) {
     assert(0 == "non-aio not supported");
   }
   // blksize doesn't strictly matter except that some file systems may
   // require a read/modify/write if we write something smaller than
   // it.
-  block_size = g_conf->bdev_block_size;
+  block_size = cct->_conf->bdev_block_size;
   if (block_size != (unsigned)st.st_blksize) {
     dout(1) << __func__ << " backing device/file reports st_blksize "
            << st.st_blksize << ", using bdev_block_size "
     return 0;
   }
   dout(10) << __func__ << " start" << dendl;
-  if (g_conf->bdev_inject_crash) {
+  if (cct->_conf->bdev_inject_crash) {
     ++injecting_crash;
     // sleep for a moment to give other threads a chance to submit or
     // wait on io that races with a flush.
     derr << __func__ << " injecting crash. first we sleep..." << dendl;
-    sleep(g_conf->bdev_inject_crash_flush_delay);
+    sleep(cct->_conf->bdev_inject_crash_flush_delay);
     derr << __func__ << " and now we die" << dendl;
-    g_ceph_context->_log->flush();
+    cct->_log->flush();
     _exit(1);
   }
   utime_t start = ceph_clock_now();
     dout(40) << __func__ << " polling" << dendl;
     int max = 16;
     FS::aio_t *aio[max];
-    int r = aio_queue.get_next_completed(g_conf->bdev_aio_poll_ms,
+    int r = aio_queue.get_next_completed(cct->_conf->bdev_aio_poll_ms,
                                         aio, max);
     if (r < 0) {
       derr << __func__ << " got " << cpp_strerror(r) << dendl;
        }
       }
     }
-    if (g_conf->bdev_debug_aio) {
+    if (cct->_conf->bdev_debug_aio) {
       utime_t now = ceph_clock_now();
       std::lock_guard<std::mutex> l(debug_queue_lock);
       if (debug_oldest) {
          debug_stall_since = now;
        } else {
          utime_t cutoff = now;
-         cutoff -= g_conf->bdev_debug_aio_suicide_timeout;
+         cutoff -= cct->_conf->bdev_debug_aio_suicide_timeout;
          if (debug_stall_since < cutoff) {
            derr << __func__ << " stalled aio " << debug_oldest
                 << " since " << debug_stall_since << ", timeout is "
-                << g_conf->bdev_debug_aio_suicide_timeout
+                << cct->_conf->bdev_debug_aio_suicide_timeout
                 << "s, suicide" << dendl;
            assert(0 == "stalled aio... buggy kernel or bad device?");
          }
       }
     }
     reap_ioc();
-    if (g_conf->bdev_inject_crash) {
+    if (cct->_conf->bdev_inject_crash) {
       ++inject_crash_count;
-      if (inject_crash_count * g_conf->bdev_aio_poll_ms / 1000 >
-         g_conf->bdev_inject_crash + g_conf->bdev_inject_crash_flush_delay) {
+      if (inject_crash_count * cct->_conf->bdev_aio_poll_ms / 1000 >
+         cct->_conf->bdev_inject_crash + cct->_conf->bdev_inject_crash_flush_delay) {
        derr << __func__ << " bdev_inject_crash trigger from aio thread"
             << dendl;
-       g_ceph_context->_log->flush();
+       cct->_log->flush();
        _exit(1);
       }
     }
 {
   dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length
           << std::dec << dendl;
-  if (g_conf->bdev_debug_inflight_ios) {
+  if (cct->_conf->bdev_debug_inflight_ios) {
     Mutex::Locker l(debug_lock);
     if (debug_inflight.intersects(offset, length)) {
       derr << __func__ << " inflight overlap of 0x"
 {
   dout(20) << __func__ << " " << aio << " 0x"
           << std::hex << offset << "~" << length << std::dec << dendl;
-  if (g_conf->bdev_debug_inflight_ios) {
+  if (cct->_conf->bdev_debug_inflight_ios) {
     Mutex::Locker l(debug_lock);
     debug_inflight.erase(offset, length);
   }
     // do not dereference txc (or it's contents) after we submit (if
     // done == true and we don't loop)
     int retries = 0;
-    if (g_conf->bdev_debug_aio) {
+    if (cct->_conf->bdev_debug_aio) {
       std::lock_guard<std::mutex> l(debug_queue_lock);
       debug_aio_link(*cur);
     }
     ioc->pending_aios.push_back(FS::aio_t(ioc, fd_direct));
     ++ioc->num_pending;
     FS::aio_t& aio = ioc->pending_aios.back();
-    if (g_conf->bdev_inject_crash &&
-       rand() % g_conf->bdev_inject_crash == 0) {
+    if (cct->_conf->bdev_inject_crash &&
+       rand() % cct->_conf->bdev_inject_crash == 0) {
       derr << __func__ << " bdev_inject_crash: dropping io 0x" << std::hex
           << off << "~" << len << std::dec
           << dendl;
   {
     dout(5) << __func__ << " 0x" << std::hex << off << "~" << len
            << std::dec << " buffered" << dendl;
-    if (g_conf->bdev_inject_crash &&
-       rand() % g_conf->bdev_inject_crash == 0) {
+    if (cct->_conf->bdev_inject_crash &&
+       rand() % cct->_conf->bdev_inject_crash == 0) {
       derr << __func__ << " bdev_inject_crash: dropping io 0x" << std::hex
           << off << "~" << len << std::dec << dendl;
       ++injecting_crash;
 
   void debug_aio_unlink(FS::aio_t& aio);
 
 public:
-  KernelDevice(aio_callback_t cb, void *cbpriv);
+  KernelDevice(CephContext* cct, aio_callback_t cb, void *cbpriv);
 
   void aio_submit(IOContext *ioc) override;
 
 
   Task(NVMEDevice *dev, IOCommand c, uint64_t off, uint64_t l, int64_t rc = 0)
     : device(dev), command(c), offset(off), len(l),
       return_code(rc),
-      start(ceph::coarse_real_clock::now(g_ceph_context)) {}
+      start(ceph::coarse_real_clock::now(cct)) {}
   ~Task() {
     assert(!io_request.nseg);
   }
     size = spdk_nvme_ns_get_sector_size(ns) * spdk_nvme_ns_get_num_sectors(ns);
     zero_command_support = spdk_nvme_ns_get_flags(ns) & SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED;
 
-    PerfCountersBuilder b(g_ceph_context, string("NVMEDevice-AIOThread-"+stringify(this)),
+    PerfCountersBuilder b(cct, string("NVMEDevice-AIOThread-"+stringify(this)),
                           l_bluestore_nvmedevice_first, l_bluestore_nvmedevice_last);
     b.add_time_avg(l_bluestore_nvmedevice_aio_write_lat, "aio_write_lat", "Average write completing latency");
     b.add_time_avg(l_bluestore_nvmedevice_read_lat, "read_lat", "Average read completing latency");
     b.add_time_avg(l_bluestore_nvmedevice_flush_queue_lat, "flush_queue_lat", "Average queue flush request latency");
     b.add_u64_counter(l_bluestore_nvmedevice_buffer_alloc_failed, "buffer_alloc_failed", "Alloc data buffer failed count");
     logger = b.create_perf_counters();
-    g_ceph_context->get_perfcounters_collection()->add(logger);
+    cct->get_perfcounters_collection()->add(logger);
     _aio_start();
   }
   ~SharedDriverData() {
-    g_ceph_context->get_perfcounters_collection()->remove(logger);
+    cct->get_perfcounters_collection()->remove(logger);
     delete logger;
   }
 
   int r = 0;
   const int max = 4;
   uint64_t lba_off, lba_count;
-  ceph::coarse_real_clock::time_point cur, start = ceph::coarse_real_clock::now(g_ceph_context);
+  ceph::coarse_real_clock::time_point cur, start
+    = ceph::coarse_real_clock::now();
   while (true) {
     bool inflight = queue_op_seq.load() - completed_op_seq.load();
  again:
             derr << __func__ << " failed to do write command" << dendl;
             ceph_abort();
           }
-          cur = ceph::coarse_real_clock::now(g_ceph_context);
+          cur = ceph::coarse_real_clock::now();
           auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(cur - start);
           logger->tinc(l_bluestore_nvmedevice_aio_write_queue_lat, dur);
           break;
             std::unique_lock<std::mutex> l(t->ctx->lock);
             t->ctx->cond.notify_all();
           } else {
-            cur = ceph::coarse_real_clock::now(g_ceph_context);
+            cur = ceph::coarse_real_clock::now(cct);
             auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(cur - start);
             logger->tinc(l_bluestore_nvmedevice_read_queue_lat, dur);
           }
             std::unique_lock<std::mutex> l(t->ctx->lock);
             t->ctx->cond.notify_all();
           } else {
-            cur = ceph::coarse_real_clock::now(g_ceph_context);
+            cur = ceph::coarse_real_clock::now();
             auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(cur - start);
             logger->tinc(l_bluestore_nvmedevice_flush_queue_lat, dur);
           }
 
         Mutex::Locker l(queue_lock);
         if (queue_empty.load()) {
-          cur = ceph::coarse_real_clock::now(g_ceph_context);
+         cur = ceph::coarse_real_clock::now(cct);
           auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(cur - start);
           logger->tinc(l_bluestore_nvmedevice_polling_lat, dur);
           if (aio_stop)
             break;
           queue_cond.Wait(queue_lock);
-          start = ceph::coarse_real_clock::now(g_ceph_context);
+          start = ceph::coarse_real_clock::now();
         }
       }
     }
 
   if (spdk_pci_device_has_non_uio_driver(pci_dev)) {
     /*NVMe kernel driver case*/
-    if (g_conf->bdev_nvme_unbind_from_kernel) {
+    if (cct->_conf->bdev_nvme_unbind_from_kernel) {
       r =  spdk_pci_device_switch_to_uio_driver(pci_dev);
       if (r < 0) {
         derr << __func__ << " device " << name
         }
 
         pci_system_init();
-        spdk_nvme_retry_count = g_conf->bdev_nvme_retry_count;
+        spdk_nvme_retry_count = cct->_conf->bdev_nvme_retry_count;
         if (spdk_nvme_retry_count < 0)
           spdk_nvme_retry_count = SPDK_NVME_DEFAULT_RETRY_COUNT;
 
   SharedDriverData *driver = task->device->get_driver();
   ++driver->completed_op_seq;
   auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(
-      ceph::coarse_real_clock::now(g_ceph_context) - task->start);
+      ceph::coarse_real_clock::now() - task->start);
   if (task->command == IOCommand::WRITE_COMMAND) {
     driver->logger->tinc(l_bluestore_nvmedevice_aio_write_lat, dur);
     assert(!spdk_nvme_cpl_is_error(completion));
 #undef dout_prefix
 #define dout_prefix *_dout << "bdev(" << name << ") "
 
-NVMEDevice::NVMEDevice(aio_callback_t cb, void *cbpriv)
-    : driver(NULL),
+NVMEDevice::NVMEDevice(CephContext* cct, aio_callback_t cb, void *cbpriv)
+  :   BlockDevice(cct),
+      driver(nullptr),
       size(0),
       block_size(0),
       aio_stop(false),
 int NVMEDevice::flush()
 {
   dout(10) << __func__ << " start" << dendl;
-  auto start = ceph::coarse_real_clock::now(g_ceph_context);
+  auto start = ceph::coarse_real_clock::now();
   driver->flush_wait();
   auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(
-      ceph::coarse_real_clock::now(g_ceph_context) - start);
+      ceph::coarse_real_clock::now() - start);
   driver->logger->tinc(l_bluestore_nvmedevice_flush_lat, dur);
   return 0;
 }
 
   aio_callback_t aio_callback;
   void *aio_callback_priv;
 
-  NVMEDevice(aio_callback_t cb, void *cbpriv);
+  NVMEDevice(CephContext* cct, aio_callback_t cb, void *cbpriv);
 
   bool supported_bdev_label() override { return false; }
 
 
 #include "bluestore_types.h"
 #include "common/debug.h"
 
-#define dout_context g_ceph_context
+#define dout_context cct
 #define dout_subsys ceph_subsys_bluestore
 #undef dout_prefix
 #define dout_prefix *_dout << "stupidalloc "
 
-StupidAllocator::StupidAllocator()
-  : num_free(0),
+StupidAllocator::StupidAllocator(CephContext* cct)
+  : cct(cct), num_free(0),
     num_reserved(0),
     free(10),
     last_alloc(0)
 
 unsigned StupidAllocator::_choose_bin(uint64_t orig_len)
 {
-  uint64_t len = orig_len / g_conf->bdev_block_size;
+  uint64_t len = orig_len / cct->_conf->bdev_block_size;
   int bin = std::min((int)cbits(len), (int)free.size() - 1);
   dout(30) << __func__ << " len 0x" << std::hex << orig_len << std::dec
           << " -> " << bin << dendl;
     skew = alloc_unit - skew;
   *offset = p.get_start() + skew;
   *length = MIN(MAX(alloc_unit, want_size), p.get_len() - skew);
-  if (g_conf->bluestore_debug_small_allocations) {
+  if (cct->_conf->bluestore_debug_small_allocations) {
     uint64_t max =
-      alloc_unit * (rand() % g_conf->bluestore_debug_small_allocations);
+      alloc_unit * (rand() % cct->_conf->bluestore_debug_small_allocations);
     if (max && *length > max) {
       dout(10) << __func__ << " shortening allocation of 0x" << std::hex
               << *length << " -> 0x"
 
 #include "os/bluestore/bluestore_types.h"
 
 class StupidAllocator : public Allocator {
+  CephContext* cct;
   std::mutex lock;
 
   int64_t num_free;     ///< total bytes in freelist
   void _insert_free(uint64_t offset, uint64_t len);
 
 public:
-  StupidAllocator();
+  StupidAllocator(CephContext* cct);
   ~StupidAllocator();
 
   int reserve(uint64_t need);
 
 
   auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
                         CODE_ENVIRONMENT_UTILITY, 0);
-  common_init_finish(g_ceph_context);
-  g_ceph_context->_conf->set_val(
+  common_init_finish(cct.get());
+  cct->_conf->set_val(
     "enable_experimental_unrecoverable_data_corrupting_features",
     "*");
-  g_ceph_context->_conf->apply_changes(NULL);
+  cct->_conf->apply_changes(NULL);
 
-  BlueFS fs;
+  BlueFS fs(&(*cct));
 
   if (args.size() != 4) {
     usage(argv);
 
   void mark_dirty(BufferHead *bh) {
     bh_set_state(bh, BufferHead::STATE_DIRTY);
     bh_lru_dirty.lru_touch(bh);
-    //bh->set_dirty_stamp(ceph_clock_now(g_ceph_context));
+    //bh->set_dirty_stamp(ceph_clock_now());
   }
 
   void bh_add(Object *ob, BufferHead *bh);
 
     AllocTest(): alloc(0) { }
     void init_alloc(int64_t size, uint64_t min_alloc_size) {
       std::cout << "Creating alloc type " << string(GetParam()) << " \n";
-      alloc.reset(Allocator::create(string(GetParam()), size, min_alloc_size));
+      alloc.reset(Allocator::create(g_ceph_context, string(GetParam()), size,
+                                   min_alloc_size));
     }
 
     void init_close() {
   if (GetParam() == std::string("stupid")) {
     return;
   }
-  int64_t blocks = BitMapArea::get_level_factor(2) * 4;
+  int64_t blocks = BitMapArea::get_level_factor(g_ceph_context, 2) * 4;
   int count = 0;
   int64_t allocated = 0;
   int64_t zone_size = 1024;
 
   BitMapArea *area = NULL;
   BitMapArea **children = new BitMapArea*[num_items];
   for (i = 0; i < num_items; i++) {
-      children[i] = new BitMapAreaLeaf(BitMapArea::get_span_size(), i, false);
+    children[i] = new BitMapAreaLeaf(
+      g_ceph_context,
+      BitMapArea::get_span_size(g_ceph_context), i, false);
   }
 
   off = 0;
   int64_t allocated = 0;
   int size = BmapEntry::size();
 
-  BmapEntry *bmap = new BmapEntry(true);
+  BmapEntry *bmap = new BmapEntry(g_ceph_context, true);
 
   // Clear bits one by one and check they are cleared
   for (i = 0; i < size; i++) {
 
   {
 
-    bmap = new BmapEntry(false);
+    bmap = new BmapEntry(g_ceph_context, false);
     start = -1;
     scanned = 0;
     allocated = 0;
     delete bmap;
   }
 
-  bmap = new BmapEntry(false);
+  bmap = new BmapEntry(g_ceph_context, false);
   bmap->set_bits(4, BmapEntry::size() - 4);
   bmap_test_assert(bmap->is_allocated(4, BmapEntry::size() - 4));
   bmap_test_assert(!bmap->is_allocated(0, 4));
   int total_blocks = 1024;
   int64_t allocated = 0;
 
-  BitMapZone *zone = new BitMapZone(total_blocks, 0);
+  BitMapZone *zone = new BitMapZone(g_ceph_context, total_blocks, 0);
 
   // Allocate all blocks and see that it is allocating in order.
   bool lock = zone->lock_excl_try();
 
     ExtentList *block_list = new ExtentList(&extents, blk_size);
 
-    zone = new BitMapZone(total_blocks, 0);
+    zone = new BitMapZone(g_ceph_context, total_blocks, 0);
     lock = zone->lock_excl_try();
     bmap_test_assert(lock);
     for (int i = 0; i < zone->size(); i += 4) {
     for (int i = 1; i <= total_blocks - BmapEntry::size(); i = i << 1) {
       for (int64_t j = 0; j <= BmapEntry::size(); j = 1 << j) {
         ExtentList *block_list = new ExtentList(&extents, blk_size);
-        zone = new BitMapZone(total_blocks, 0);
+       zone = new BitMapZone(g_ceph_context, total_blocks, 0);
         lock = zone->lock_excl_try();
         bmap_test_assert(lock);
 
     //allocation in loop
     {
       ExtentList *block_list = new ExtentList(&extents, blk_size);
-      zone = new BitMapZone(total_blocks, 0);
+      zone = new BitMapZone(g_ceph_context, total_blocks, 0);
       lock = zone->lock_excl_try();
 
       for (int iter = 1; iter < 5; iter++) {
     {
 
         ExtentList *block_list = new ExtentList(&extents, blk_size);
-        zone = new BitMapZone(total_blocks, 0);
+       zone = new BitMapZone(g_ceph_context, total_blocks, 0);
         lock = zone->lock_excl_try();
         bmap_test_assert(lock);
 
     int64_t total_blocks = zone_size * 4;
     int64_t allocated = 0;
 
-    BitAllocator *alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
-   
+    BitAllocator *alloc = new BitAllocator(g_ceph_context, total_blocks,
+                                          zone_size, CONCURRENT);
     int64_t alloc_size = 2;
     for (int64_t iter = 0; iter < max_iter; iter++) {
       for (int64_t j = 0; alloc_size <= total_blocks; j++) {
 {
   int64_t total_blocks = 1024 * 4;
   int64_t zone_size = 1024;
-  BitAllocator *alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
+  BitAllocator *alloc = new BitAllocator(g_ceph_context, total_blocks,
+                                        zone_size, CONCURRENT);
 
   alloc_extents_max_block(alloc, 1, 16);
   alloc_extents_max_block(alloc, 4, 16);
 
   bmap_test_assert(total_blocks <= MAX_BLOCKS);
 
-  BitAllocator *alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
+  BitAllocator *alloc = new BitAllocator(g_ceph_context, total_blocks,
+                                        zone_size, CONCURRENT);
 
   for (int k = 0; k < 2; k++) {
     cont = k;
 
   uint64_t size = 1048576 * 128;
   string fn = get_temp_bdev(size);
   uuid_d fsid;
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   fs.add_block_device(BlueFS::BDEV_DB, fn);
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   fs.mkfs(fsid);
 TEST(BlueFS, mkfs_mount) {
   uint64_t size = 1048576 * 128;
   string fn = get_temp_bdev(size);
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
 TEST(BlueFS, write_read) {
   uint64_t size = 1048576 * 128;
   string fn = get_temp_bdev(size);
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
 TEST(BlueFS, small_appends) {
   uint64_t size = 1048576 * 128;
   string fn = get_temp_bdev(size);
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
     "65536");
   g_ceph_context->_conf->apply_changes(NULL);
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
     "65536");
   g_ceph_context->_conf->apply_changes(NULL);
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
     "65536");
   g_ceph_context->_conf->apply_changes(NULL);
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
   uint64_t size = 1048576 * 128;
   string fn = get_temp_bdev(size);
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
   uint64_t size = 1048576 * 128;
   string fn = get_temp_bdev(size);
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
     "bluefs_compact_log_sync",
     "true");
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
     "bluefs_compact_log_sync",
     "false");
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
     "bluefs_compact_log_sync",
     "false");
 
-  BlueFS fs;
+  BlueFS fs(g_ceph_context);
   ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn));
   fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
   uuid_d fsid;
 
-// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
 #include "include/types.h"
 TEST(Blob, put_ref)
 {
   {
-    BlueStore::Blob b;
+    BlueStore::Blob b(g_ceph_context);
     b.shared_blob = new BlueStore::SharedBlob(nullptr);
     b.shared_blob->get();  // hack to avoid dtor from running
     b.dirty_blob().extents.push_back(bluestore_pextent_t(0x40715000, 0x2000));
     r.clear();
     b.put_ref(0xae00, 0x4200, 0x1000, &r);
     cout << " r " << r << std::endl;
-    cout << b << std::endl;  
+    cout << b << std::endl;
   }
 
   unsigned mas = 4096;
   unsigned mrs = 8192;
 
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_EQ(mas*2, b.extents[0].length);
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_EQ(mas*2, b.extents[0].length);
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_EQ(3u, b.extents.size());
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_TRUE(b.extents[4].is_valid());
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_TRUE(b.extents[2].is_valid());
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_TRUE(b.extents[2].is_valid());
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_FALSE(b.extents[0].is_valid());
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_FALSE(b.extents[0].is_valid());
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
   }
   // verify csum chunk size if factored in properly
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
     ASSERT_EQ(mas*4, b.extents[0].length);
   }
   {
-    BlueStore::Blob B;
+    BlueStore::Blob B(g_ceph_context);
     B.shared_blob = new BlueStore::SharedBlob(nullptr);
     B.shared_blob->get();  // hack to avoid dtor from running
     bluestore_blob_t& b = B.dirty_blob();
 
 TEST(Blob, split)
 {
-  BlueStore::Cache *cache = BlueStore::Cache::create("lru", NULL);
+  BlueStore::Cache *cache = BlueStore::Cache::create(
+    g_ceph_context, "lru", NULL);
   {
-    BlueStore::Blob L, R;
+    BlueStore::Blob L(g_ceph_context), R(g_ceph_context);
     L.shared_blob = new BlueStore::SharedBlob(cache);
     L.shared_blob->get();  // hack to avoid dtor from running
     R.shared_blob = new BlueStore::SharedBlob(cache);
     ASSERT_EQ(0x1000u, R.get_blob().extents.front().length);
   }
   {
-    BlueStore::Blob L, R;
+    BlueStore::Blob L(g_ceph_context), R(g_ceph_context);
     L.shared_blob = new BlueStore::SharedBlob(cache);
     L.shared_blob->get();  // hack to avoid dtor from running
     R.shared_blob = new BlueStore::SharedBlob(cache);
 
 TEST(ExtentMap, find_lextent)
 {
-  BlueStore::LRUCache cache;
-  BlueStore::ExtentMap em(nullptr);
-  BlueStore::BlobRef br(new BlueStore::Blob);
+  BlueStore::LRUCache cache(g_ceph_context);
+  BlueStore::ExtentMap em(g_ceph_context, nullptr);
+  BlueStore::BlobRef br(new BlueStore::Blob(g_ceph_context));
   br->shared_blob = new BlueStore::SharedBlob(&cache);
 
   ASSERT_EQ(em.extent_map.end(), em.find_lextent(0));
 
 TEST(ExtentMap, seek_lextent)
 {
-  BlueStore::LRUCache cache;
-  BlueStore::ExtentMap em(nullptr);
-  BlueStore::BlobRef br(new BlueStore::Blob);
+  BlueStore::LRUCache cache(g_ceph_context);
+  BlueStore::ExtentMap em(g_ceph_context, nullptr);
+  BlueStore::BlobRef br(new BlueStore::Blob(g_ceph_context));
   br->shared_blob = new BlueStore::SharedBlob(&cache);
 
   ASSERT_EQ(em.extent_map.end(), em.seek_lextent(0));
 
 TEST(ExtentMap, has_any_lextents)
 {
-  BlueStore::LRUCache cache;
-  BlueStore::ExtentMap em(nullptr);
-  BlueStore::BlobRef b(new BlueStore::Blob);
+  BlueStore::LRUCache cache(g_ceph_context);
+  BlueStore::ExtentMap em(g_ceph_context, nullptr);
+  BlueStore::BlobRef b(new BlueStore::Blob(g_ceph_context));
   b->shared_blob = new BlueStore::SharedBlob(&cache);
 
   ASSERT_FALSE(em.has_any_lextents(0, 0));
 
 TEST(ExtentMap, compress_extent_map)
 {
-  BlueStore::LRUCache cache;
-  BlueStore::ExtentMap em(nullptr);
-  BlueStore::BlobRef b1(new BlueStore::Blob);
-  BlueStore::BlobRef b2(new BlueStore::Blob);
-  BlueStore::BlobRef b3(new BlueStore::Blob);
+  BlueStore::LRUCache cache(g_ceph_context);
+  BlueStore::ExtentMap em(g_ceph_context, nullptr);
+  BlueStore::BlobRef b1(new BlueStore::Blob(g_ceph_context));
+  BlueStore::BlobRef b2(new BlueStore::Blob(g_ceph_context));
+  BlueStore::BlobRef b3(new BlueStore::Blob(g_ceph_context));
   b1->shared_blob = new BlueStore::SharedBlob(&cache);
   b2->shared_blob = new BlueStore::SharedBlob(&cache);
   b3->shared_blob = new BlueStore::SharedBlob(&cache);