int64_t BitMapZone::count = 0;
 int64_t BitMapZone::total_blocks = 0;
 
+bool BmapEntry::m_bit_mask_init = false;
+bmap_mask_vec_t BmapEntry::m_bit_to_mask;
+
 /*
  * BmapEntityList functions.
  */
 /*
  * Bitmap Entry functions.
  */
+
+void BmapEntry::_init_bit_mask()
+{
+
+  if (m_bit_mask_init) {
+    return;
+  }
+
+  m_bit_to_mask.reserve(BmapEntry::size());
+
+  uint64_t bmask = ((bmap_t) 0x1 << (BmapEntry::size() - 1));
+  for (int i = 0; i < BmapEntry::size(); i++) {
+    m_bit_to_mask[i] = bmask >> i; 
+  }
+  BmapEntry::m_bit_mask_init = true;
+}
+
 BmapEntry::BmapEntry(bool full)
 {
+
+  BmapEntry::_init_bit_mask();
+
   if (full) {
     m_bits = BmapEntry::full_bmask();
   } else {
 
 bmap_t BmapEntry::bit_mask(int bit)
 {
-  return ((bmap_t) 0x1 << ((BmapEntry::size() - 1) - bit));
+  return m_bit_to_mask[bit];
+//  return ((bmap_t) 0x1 << ((BmapEntry::size() - 1) - bit));
 }
 bool BmapEntry::check_bit(int bit)
 {
 /*
  * Allocate N blocks, dis-contiguous are fine
  */
+#if 0
 int64_t BitMapZone::alloc_blocks_dis(int64_t num_blocks,
                                int64_t hint,
                                    int64_t zone_blk_off, 
 
   return allocated;
 }
+#endif 
 
-int64_t BitMapZone::alloc_blocks_dis2(int64_t num_blocks,
+int64_t BitMapZone::alloc_blocks_dis(int64_t num_blocks,
            int64_t min_alloc,
-          int64_t hint,
-          int64_t zone_blk_off, 
-          ExtentList *alloc_blocks)
+     int64_t hint,
+     int64_t zone_blk_off, 
+     ExtentList *alloc_blocks)
 {
   int64_t bmap_idx = hint / BmapEntry::size();
   int bit = hint % BmapEntry::size();
 
   BitMapEntityIter <BmapEntry> iter = BitMapEntityIter<BmapEntry>(
           m_bmap_list, bmap_idx);
+  bmap = iter.next();
 
   while (allocated < num_blocks) {
-               blk_off = zone_blk_off + bmap_idx * size();
-               if (last_cont) {
-                       /*
-                        * We had bits free at end of last bitmap, try to complete required
-                        * min alloc size using that.
-                        */
-                       alloc_cont = bmap->find_n_cont_bits(0, min_alloc - last_cont);
-                       allocated += alloc_cont;
-                       last_cont += alloc_cont;
-                       
-                       if (!alloc_cont) {
-                               this->free_blocks(last_running_ext, last_cont);
-                               allocated -= last_cont;
-                               last_cont = 0;
-                       } else {
-                               /*
-                                * Got contiguous min_alloc_size across bitmaps.
-                                */
-                               alloc_blocks->add_extents(last_running_ext, last_cont);
-                       }
-                       last_running_ext = 0;
-                       search_idx = alloc_cont;
-               } else {
-                       /*
-                        * Try to allocate  min_alloc_size bits from given bmap.
-                        */
-                       alloc_cont = bmap->find_first_set_bits(min_alloc, search_idx, &start_off, &scanned);
-                       search_idx = search_idx + scanned;
-                       if (alloc_cont / min_alloc) {
-                               /*
-       * Got contiguous min_alloc_size within a bitmap.
+    blk_off = zone_blk_off + bmap_idx * bmap->size();
+    if (last_cont) {
+      /*
+       * We had bits free at end of last bitmap, try to complete required
+       * min alloc size using that.
+       */
+      alloc_cont = bmap->find_n_cont_bits(0, min_alloc - last_cont);
+      allocated += alloc_cont;
+      last_cont += alloc_cont;
+      
+      if (!alloc_cont) {
+        this->free_blocks_int(last_running_ext, last_cont);
+        allocated -= last_cont;
+        last_cont = 0;
+      } else if (last_cont / min_alloc) {
+          /*
+           * Got contiguous min_alloc_size across bitmaps.
+           */
+          alloc_blocks->add_extents(last_running_ext, last_cont);
+          last_cont = 0;
+          last_running_ext = 0;
+      }
+      search_idx = alloc_cont;
+    } else {
+      /*
+       * Try to allocate  min_alloc_size bits from given bmap.
        */
-      alloc_blocks->add_extents(blk_off + start_off, min_alloc);
-                       }
-                       
-                       if (alloc_cont % min_alloc) {
-                               /*
-                                * Got some bits at end of bitmap, carry them to try match with
-                                * start bits from next bitmap.
-                                */
-                               if (!last_cont) {
-                                       last_running_ext = blk_off + start_off;
-                               } 
-                               last_cont += alloc_cont % min_alloc;
-                       }
-               }
+      alloc_cont = bmap->find_first_set_bits(min_alloc, search_idx, &start_off, &scanned);
+      search_idx = search_idx + scanned;
+      allocated += alloc_cont;
+      if (alloc_cont / min_alloc) {
+        /*
+         * Got contiguous min_alloc_size within a bitmap.
+         */
+        alloc_blocks->add_extents(blk_off + start_off, min_alloc);
+      }
+      
+      if (alloc_cont % min_alloc) {
+        /*
+         * Got some bits at end of bitmap, carry them to try match with
+         * start bits from next bitmap.
+         */
+        if (!last_cont) {
+          last_running_ext = blk_off + start_off;
+        } 
+        last_cont += alloc_cont % min_alloc;
+      }
+    }
   
    
-               if (search_idx == BmapEntry::size()) {
-                       search_idx = 0;
-                       if ((bmap = iter.next())) {
-                               this->free_blocks(last_running_ext, last_cont);
-                               allocated -= last_cont;
-                               break;
-                       }
-               }
-       }
+    if (search_idx == BmapEntry::size()) {
+      search_idx = 0;
+      bmap_idx = iter.index();
+      if ((bmap = iter.next()) == NULL) {
+        this->free_blocks_int(last_running_ext, last_cont);
+        allocated -= last_cont;
+        break;
+      }
+    }
+  }
 
-       return allocated;
+  add_used_blocks(allocated);
+  return allocated;
 }
 
 
   return allocated;
 }
 
-int64_t BitMapAreaIN::alloc_blocks_dis_int_work(bool wait, bool wrap, int64_t num_blocks,
+int64_t BitMapAreaIN::alloc_blocks_dis_int_work(bool wait, bool wrap, int64_t num_blocks, int64_t min_alloc, 
            int64_t hint, int64_t area_blk_off, ExtentList *block_list)
 {
   BitMapArea *child = NULL;
     }
 
     blk_off = child->get_index() * m_child_size_blocks + area_blk_off;
-    allocated += child->alloc_blocks_dis(wait, num_blocks - allocated,
+    allocated += child->alloc_blocks_dis(wait, num_blocks - allocated, min_alloc,
                             hint % m_child_size_blocks, blk_off, block_list);
     hint = 0;
     child_unlock(child);
 }
 
 int64_t BitMapAreaIN::alloc_blocks_dis_int(bool wait, int64_t num_blocks,
-           int64_t hint, int64_t area_blk_off, ExtentList *block_list)
+           int64_t min_alloc, int64_t hint, int64_t area_blk_off, ExtentList *block_list)
 {
-  return alloc_blocks_dis_int_work(wait, false, num_blocks, hint,
+  return alloc_blocks_dis_int_work(wait, false, num_blocks, min_alloc, hint,
                      area_blk_off, block_list);
 }
 
-int64_t BitMapAreaIN::alloc_blocks_dis(bool wait, int64_t num_blocks,
+int64_t BitMapAreaIN::alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc,
            int64_t hint, int64_t blk_off, ExtentList *block_list)
 {
   int64_t allocated = 0;
 
   lock_shared();
-  allocated += alloc_blocks_dis_int(wait, num_blocks, hint, blk_off, block_list);
+  allocated += alloc_blocks_dis_int(wait, num_blocks, min_alloc, hint, blk_off, block_list);
   add_used_blocks(allocated);
 
   unlock();
   return allocated;
 }
 
-int64_t BitMapAreaLeaf::alloc_blocks_dis_int(bool wait, int64_t num_blocks,
+int64_t BitMapAreaLeaf::alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc, 
                                  int64_t hint, int64_t area_blk_off, ExtentList *block_list)
 {
   BitMapArea *child = NULL;
     }
 
     blk_off = child->get_index() * m_child_size_blocks + area_blk_off;
-    allocated += child->alloc_blocks_dis(num_blocks - allocated, hint % m_child_size_blocks,
-                                         blk_off, block_list);
+    allocated += child->alloc_blocks_dis(num_blocks - allocated, min_alloc,
+                                         hint % m_child_size_blocks, blk_off, block_list);
     child_unlock(child);
     if (allocated == num_blocks) {
       break;
  * Allocate N dis-contiguous blocks.
  */
 int64_t BitAllocator::alloc_blocks_dis_int(bool wait, int64_t num_blocks,
-           int64_t hint, int64_t area_blk_off, ExtentList *block_list)
+           int64_t min_alloc, int64_t hint, int64_t area_blk_off, ExtentList *block_list)
 {
-  return alloc_blocks_dis_int_work(wait, true, num_blocks, hint,
+  return alloc_blocks_dis_int_work(wait, true, num_blocks, min_alloc, hint,
                      area_blk_off, block_list);
 }
 
-int64_t BitAllocator::alloc_blocks_dis(int64_t num_blocks, int64_t hint, ExtentList *block_list)
+int64_t BitAllocator::alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list)
 {
-  return alloc_blocks_dis_work(num_blocks, hint, block_list, false);
+  return alloc_blocks_dis_work(num_blocks, min_alloc, hint, block_list, false);
 }
 
-int64_t BitAllocator::alloc_blocks_dis_res(int64_t num_blocks, int64_t hint, ExtentList *block_list)
+int64_t BitAllocator::alloc_blocks_dis_res(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list)
 {
-  return alloc_blocks_dis_work(num_blocks, hint, block_list, true);
+  return alloc_blocks_dis_work(num_blocks, min_alloc, hint, block_list, true);
 }
 
-int64_t BitAllocator::alloc_blocks_dis_work(int64_t num_blocks, int64_t hint, ExtentList *block_list, bool reserved)
+int64_t BitAllocator::alloc_blocks_dis_work(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list, bool reserved)
 {
   int scans = 1;
   int64_t allocated = 0;
   }
 
   while (scans && allocated < num_blocks) {
-    allocated += alloc_blocks_dis_int(false, num_blocks - allocated, hint + allocated, blk_off, block_list);
+    allocated += alloc_blocks_dis_int(false, num_blocks - allocated, min_alloc, hint + allocated, blk_off, block_list);
     scans--;
   }
 
     unlock();
     lock_excl();
     serial_lock();
-    allocated += alloc_blocks_dis_int(false, num_blocks - allocated, hint + allocated,
+    allocated += alloc_blocks_dis_int(false, num_blocks - allocated, min_alloc, hint + allocated,
                                       blk_off, block_list);
     if (is_stats_on()) {
       m_stats->add_serial_scans(1);
 
 };
 
 typedef unsigned long bmap_t;
+typedef mempool::bluestore_alloc::vector<bmap_t> bmap_mask_vec_t;
 
 class BmapEntry {
 
 private:
   bmap_t m_bits;
+  static bool m_bit_mask_init;
+  static bmap_mask_vec_t m_bit_to_mask;
+
+
+  static void _init_bit_mask();
 
 public:
   MEMPOOL_CLASS_HELPERS();
   static int64_t size();
   static bmap_t empty_bmask();
   static bmap_t align_mask(int x);
-  bmap_t bit_mask(int bit_num);
+  static bmap_t bit_mask(int bit_num);
   bmap_t atomic_fetch();
   BmapEntry(bool val);
   BmapEntry() {
     return 0;
   }
 
-  virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks,
+  virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc,
              int64_t hint, int64_t blk_off, ExtentList *block_list) {
     ceph_abort();
     return 0;
   }
-  virtual int64_t alloc_blocks_dis(int64_t num_blocks,
+  virtual int64_t alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc,
              int64_t hint, int64_t blk_off, ExtentList *block_list) {
     ceph_abort();
     return 0;
     return 0;
   }
 
-  virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks,
+  virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc,
              int64_t hint, int64_t blk_off, int64_t *block_list) {
     ceph_abort();
     return 0;
 
   int64_t alloc_blocks(int64_t num_blocks, int64_t hint, int64_t *start_block);
   using BitMapArea::alloc_blocks_dis;
-  int64_t alloc_blocks_dis(int64_t num_blocks, int64_t hint,
-        int64_t blk_off, ExtentList *block_list);  
-  int64_t alloc_blocks_dis2(int64_t num_blocks, int64_t min_alloc, int64_t hint,
+  int64_t alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc, int64_t hint,
         int64_t blk_off, ExtentList *block_list);  
   void set_blocks_used(int64_t start_block, int64_t num_blocks);
 
 
   int64_t alloc_blocks_int_work(bool wait, bool wrap,
                          int64_t num_blocks, int64_t hint, int64_t *start_block);
-  int64_t alloc_blocks_dis_int_work(bool wait, bool wrap, int64_t num_blocks, int64_t hint,
+  int64_t alloc_blocks_dis_int_work(bool wait, bool wrap, int64_t num_blocks, int64_t min_alloc, int64_t hint,
         int64_t blk_off, ExtentList *block_list);  
 
 public:
   }
 
   virtual int64_t alloc_blocks_int(bool wait, int64_t num_blocks,
-                 int64_t hint, int64_t *start_block);
+                                   int64_t hint, int64_t *start_block);
   using BitMapArea::alloc_blocks; //non-wait version
   using BitMapArea::alloc_blocks_dis; //non-wait version
   virtual int64_t alloc_blocks(bool wait, int64_t num_blocks, int64_t hint, int64_t *start_block);
-  virtual int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t hint,
+  virtual int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc, int64_t hint,
         int64_t blk_off, ExtentList *block_list);  
-  virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t hint,
+  virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc, int64_t hint,
         int64_t blk_off, ExtentList *block_list);  
   virtual void set_blocks_used_int(int64_t start_block, int64_t num_blocks);
   virtual void set_blocks_used(int64_t start_block, int64_t num_blocks);
   void child_unlock(BitMapArea *child);
 
   int64_t alloc_blocks_int(bool wait, int64_t num_blocks, int64_t hint, int64_t *start_block);
-  int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t hint,
+  int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc, int64_t hint,
         int64_t blk_off, ExtentList *block_list);  
   void free_blocks_int(int64_t start_block, int64_t num_blocks);
 
   bool check_input_dis(int64_t num_blocks);
   void init_check(int64_t total_blocks, int64_t zone_size_block,
                  bmap_alloc_mode_t mode, bool def, bool stats_on);
-  int64_t alloc_blocks_dis_work(int64_t num_blocks, int64_t hint, ExtentList *block_list, bool reserved);
+  int64_t alloc_blocks_dis_work(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list, bool reserved);
   int64_t alloc_blocks_int(bool wait, int64_t num_blocks, int64_t hint, int64_t *start_block);
 
-  int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks,
+  int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc, 
            int64_t hint, int64_t area_blk_off, ExtentList *block_list);
 
 public:
   void set_blocks_used(int64_t start_block, int64_t num_blocks);
   void unreserve_blocks(int64_t blocks);
 
-  int64_t alloc_blocks_dis(int64_t num_blocks, int64_t hint, ExtentList *block_list);
-  int64_t alloc_blocks_dis_res(int64_t num_blocks, int64_t hint, ExtentList *block_list);
+  int64_t alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list);
+  int64_t alloc_blocks_dis_res(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list);
 
   void free_blocks_dis(int64_t num_blocks, ExtentList *block_list);
   bool is_allocated_dis(ExtentList *blocks, int64_t num_blocks);
 
   uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
   int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count)
 {
+
   assert(!(alloc_unit % m_block_size));
   assert(alloc_unit);
 
      << " hint " << hint
      << dendl;
 
-  if (alloc_unit > (uint64_t) m_block_size) {
-    return alloc_extents_cont(want_size, alloc_unit, 
-                              max_alloc_size, hint / m_block_size, extents, count);     
-  } else {
-    return alloc_extents_dis(want_size, alloc_unit,
-                             max_alloc_size, hint / m_block_size, extents, count); 
-  }
+  return alloc_extents_dis(want_size, alloc_unit / m_block_size,
+                           max_alloc_size, hint / m_block_size, extents, count); 
 }
 
 /*
   int64_t num = 0;
   *count = 0;
 
-  num = m_bit_alloc->alloc_blocks_dis_res(nblks, hint, &block_list);
+  num = m_bit_alloc->alloc_blocks_dis_res(nblks, alloc_unit, hint, &block_list);
   if (num < nblks) {
     m_bit_alloc->free_blocks_dis(num, &block_list);
     return -ENOSPC;
 
 #include <gtest/gtest.h>
 
 
-#define bmap_test_assert(x) ASSERT_EQ(true, (x))
+//#define bmap_test_assert(x) ASSERT_EQ(true, (x))
+#define bmap_test_assert(x) assert((x))
 #define NUM_THREADS 16
 #define MAX_BLOCKS (1024 * 1024 * 1)
 
         (zone->size() / 2, AllocExtent(-1, -1));
 
   ExtentList *block_list = new ExtentList(&extents, blk_size);
-  allocated = zone->alloc_blocks_dis(zone->size() / 2, 0, 0, block_list);
+  allocated = zone->alloc_blocks_dis(zone->size() / 2, 1, 0, 0, block_list);
   bmap_test_assert(allocated == zone->size() / 2);
 
   {
     bmap_test_assert(lock);
     for (int i = 0; i < zone->size(); i += 4) {
       block_list->reset();
-      allocated = zone->alloc_blocks_dis(1, i, 0, block_list);
+      allocated = zone->alloc_blocks_dis(1, 1, i, 0, block_list);
       bmap_test_assert(allocated == 1);
       EXPECT_EQ(extents[0].offset, (uint64_t) i * blk_size);
     }
       zone->free_blocks(i, 1);
     }
   }
+
+  /*
+   * Min alloc size cases.
+   */
+  {
+    int64_t blk_size = 1;
+    AllocExtentVector extents = AllocExtentVector
+      (zone->size() / 2, AllocExtent(-1, -1));
+
+    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);
+        lock = zone->lock_excl_try();
+        bmap_test_assert(lock);
+
+        block_list->reset();
+        int64_t need_blks = (((total_blocks - j) / i) * i);
+        allocated = zone->alloc_blocks_dis(need_blks, i, j, 0, block_list);
+        bmap_test_assert(allocated == need_blks);
+        bmap_test_assert(extents[0].offset ==  (uint64_t) j);
+        delete block_list;
+        delete zone;
+      }
+    }
+    {
+        ExtentList *block_list = new ExtentList(&extents, blk_size);
+        zone = new BitMapZone(total_blocks, 0);
+        lock = zone->lock_excl_try();
+        bmap_test_assert(lock);
+
+        block_list->reset();
+        allocated = zone->alloc_blocks_dis(total_blocks + 1, total_blocks + 1, 0, 0, block_list);
+        bmap_test_assert(allocated == 0);  
+
+        block_list->reset();
+        allocated = zone->alloc_blocks_dis(total_blocks, total_blocks, 0, 0, block_list);
+        bmap_test_assert(allocated == total_blocks);
+        bmap_test_assert(extents[0].offset == 0);
+
+        zone->free_blocks(extents[0].offset, allocated);        
+        
+        delete block_list;  
+        block_list = new ExtentList(&extents, blk_size, total_blocks / 4 * blk_size);
+        block_list->reset();
+        allocated = zone->alloc_blocks_dis(total_blocks, total_blocks / 4, 0, 0, block_list);
+        bmap_test_assert(allocated == total_blocks);
+        for (int i = 0; i < 4; i++) {
+          bmap_test_assert(extents[i].offset == (uint64_t) i * (total_blocks / 4));
+        }
+  
+    }
+  }
 }
 
 TEST(BitAllocator, test_bmap_alloc)
 
     ExtentList *block_list = new ExtentList(&extents, blk_size);
 
-    allocated = alloc->alloc_blocks_dis(alloc->size()/2, 0, block_list);
+    allocated = alloc->alloc_blocks_dis(alloc->size()/2, 1, 0, block_list);
     ASSERT_EQ(alloc->size()/2, allocated);
 
     block_list->reset();
-    allocated = alloc->alloc_blocks_dis(1, 0, block_list);
+    allocated = alloc->alloc_blocks_dis(1, 1, 0, block_list);
     bmap_test_assert(allocated == 0);
 
     alloc->free_blocks(alloc->size()/2, 1);
 
     block_list->reset();
-    allocated = alloc->alloc_blocks_dis(1, 0, block_list);
+    allocated = alloc->alloc_blocks_dis(1, 1, 0, block_list);
     bmap_test_assert(allocated == 1);
 
     bmap_test_assert((int64_t) extents[0].offset == alloc->size()/2 * blk_size);
 
   ExtentList *block_list = new ExtentList(&extents, blk_size, max_alloc);
 
-  allocated = alloc->alloc_blocks_dis(total_alloc, 0, block_list);
+  allocated = alloc->alloc_blocks_dis(total_alloc, blk_size, 0, block_list);
   EXPECT_EQ(allocated, total_alloc);
 
   max_alloc = total_alloc > max_alloc? max_alloc: total_alloc;
 
   while (num_iters--) {
       alloc_assert(alloc->reserve_blocks(num_blocks));
-      alloced = alloc->alloc_blocks_dis_res(num_blocks, 0, block_list);
+      alloced = alloc->alloc_blocks_dis_res(num_blocks, 1, 0, block_list);
       alloc_assert(alloced == num_blocks);
 
       alloc_assert(alloc->is_allocated_dis(block_list, num_blocks));