]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/BitMapAllocator: fix free space beyond size of BitAllocator
authorJianpeng Ma <jianpeng.ma@intel.com>
Mon, 6 Jun 2016 23:37:13 +0000 (07:37 +0800)
committerJianpeng Ma <jianpeng.ma@intel.com>
Mon, 6 Jun 2016 23:37:13 +0000 (07:37 +0800)
When Using bitmap allocator, the osd crashed. The stack info as
follows:

ceph-osd: os/bluestore/BitAllocator.cc:910: bool
BitAllocator::is_allocated(int64_t, int64_t): Assertion `start_block >=
0 && (start_block + num_blocks <= size())' failed.
*** Caught signal (Aborted) **
in thread 7f795bbc48c0 thread_name:ceph-osd ceph version
10.2.0-1333-g3f4cf16
(3f4cf16)
1: (()+0x98e25e) [0x55e112a9625e]
2: (()+0x109f0) [0x7f795a6719f0]
3: (gsignal()+0x38) [0x7f7958542a28]
4: (abort()+0x16a) [0x7f795854462a]
5: (()+0x2d227) [0x7f795853b227]
6: (()+0x2d2d2) [0x7f795853b2d2]
7: (()+0x7eaa59) [0x55e1128f2a59]
8: (BitAllocator::free_blocks(long, long)+0x22) [0x55e1128f2e82]
9: (BitMapAllocator::insert_free(unsigned long, unsigned long)+0x22c)
[0x55e1128ef12c]
10: (BitMapAllocator::init_add_free(unsigned long, unsigned long)+0x22c)
[0x55e1128ef41c]
11: (BlueFS::_init_alloc()+0x2b9) [0x55e1128c27b9]
12: (BlueFS::mkfs(uuid_d)+0x45a) [0x55e1128d475a]
13: (BlueStore::_open_db(bool)+0xd76) [0x55e1127bbcb6]
14: (BlueStore::mkfs()+0x8b1) [0x55e1127e4f11]
15: (OSD::mkfs(CephContext, ObjectStore, std::__cxx11::basic_string,
std::allocator > const&, uuid_d, int)+0x117) [0x55e112484de7]
16: (main()+0x101f) [0x55e112425f2f]
17: (__libc_start_main()+0xf0) [0x7f795852e580]
18: (_start()+0x29) [0x55e1124684e9]

This because in BitAllocator::init will decrease size of blkdev which
make size align w/ zone-size.
The later add free extent will beyond the size.

Signed-off-by: Jianpeng Ma <jianpeng.ma@intel.com>
src/os/bluestore/BitAllocator.cc
src/os/bluestore/BitAllocator.h
src/os/bluestore/BitMapAllocator.cc

index 4895dba5bf948c1f97d9a7b978665044aac037ae..99d8d67bf750252040add9fb0ac33ce344c45b3a 100644 (file)
@@ -1262,6 +1262,7 @@ void BitAllocator::init_check(int64_t total_blocks, int64_t zone_size_block,
     debug_assert(0);
   }
 
+  truncated_blocks = total_blocks - (total_blocks / zone_size_block) * zone_size_block;
   total_blocks = (total_blocks / zone_size_block) * zone_size_block;
   total_zones = total_blocks / zone_size_block;
 
index 011a149dc3ad1a17752eb34b5c002109b58c15d7..409dc90f40d343a410a06f8c8542f0351b8ccb7b 100644 (file)
@@ -458,6 +458,8 @@ private:
   BitAllocatorStats *m_stats;
   bool m_is_stats_on;
 
+  int64_t truncated_blocks; //see init_check
+
   bool is_stats_on() {
     return m_is_stats_on;
   }
@@ -493,6 +495,7 @@ public:
   int64_t alloc_blocks_dis(int64_t num_blocks, int64_t *block_list);
   void free_blocks_dis(int64_t num_blocks, int64_t *block_list);
 
+  int64_t get_truncated_blocks() { return truncated_blocks; }
   BitAllocatorStats *get_stats() {
       return m_stats;
   }
index 1fdb0b5d491cb3b67c97ea322a67b5ca7352bb0e..00aa078c5b96a706e9cefaf6d99d210971926d7e 100644 (file)
@@ -161,8 +161,16 @@ void BitMapAllocator::init_add_free(uint64_t offset, uint64_t length)
   dout(10) << __func__ <<" instance "<< (uint64_t) this <<
     " offset " << offset << " length " << length << dendl;
 
-  insert_free(NEXT_MULTIPLE(offset, m_block_size),
-      (length / m_block_size) * m_block_size);
+  offset = NEXT_MULTIPLE(offset, m_block_size);
+
+  // bitallocator::init may decrease the size of blkdev.
+  uint64_t total_size = m_bit_alloc->size() * m_block_size;
+  if (offset + length > total_size) {
+    assert(offset + length < total_size + m_bit_alloc->get_truncated_blocks() * m_block_size);
+    length -= (offset + length) - total_size;
+  }
+
+  insert_free(offset, (length / m_block_size) * m_block_size);
 }
 
 void BitMapAllocator::init_rm_free(uint64_t offset, uint64_t length)