From fca97f8619b33141217dcef5f06e45fb513ca6d1 Mon Sep 17 00:00:00 2001 From: Jianpeng Ma Date: Tue, 7 Jun 2016 07:37:13 +0800 Subject: [PATCH] os/bluestore/BitMapAllocator: fix free space beyond size of BitAllocator 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 --- src/os/bluestore/BitAllocator.cc | 1 + src/os/bluestore/BitAllocator.h | 3 +++ src/os/bluestore/BitMapAllocator.cc | 12 ++++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/os/bluestore/BitAllocator.cc b/src/os/bluestore/BitAllocator.cc index 4895dba5bf948..99d8d67bf7502 100644 --- a/src/os/bluestore/BitAllocator.cc +++ b/src/os/bluestore/BitAllocator.cc @@ -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; diff --git a/src/os/bluestore/BitAllocator.h b/src/os/bluestore/BitAllocator.h index 011a149dc3ad1..409dc90f40d34 100644 --- a/src/os/bluestore/BitAllocator.h +++ b/src/os/bluestore/BitAllocator.h @@ -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; } diff --git a/src/os/bluestore/BitMapAllocator.cc b/src/os/bluestore/BitMapAllocator.cc index 1fdb0b5d491cb..00aa078c5b96a 100644 --- a/src/os/bluestore/BitMapAllocator.cc +++ b/src/os/bluestore/BitMapAllocator.cc @@ -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) -- 2.39.5