From 8eb51539bb64840a043c59f99e28478f327877b5 Mon Sep 17 00:00:00 2001 From: lisali Date: Tue, 13 Jun 2017 09:44:25 -0400 Subject: [PATCH] bluestore: wrap blob id when it reaches maximum value of int16_t Blob id exceeds maximum value, this patch is to prevent it. Fixes: http://tracker.ceph.com/issues/19555 Signed-off-by: Xiaoyan Li --- src/os/bluestore/BlueStore.cc | 35 +++++++++++++++++++++++++++-------- src/os/bluestore/BlueStore.h | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index e8998683392..2252dd89c16 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -36,6 +36,8 @@ #define dout_context cct #define dout_subsys ceph_subsys_bluestore +using bid_t = decltype(BlueStore::Blob::id); + // bluestore_cache_onode MEMPOOL_DEFINE_OBJECT_FACTORY(BlueStore::Onode, bluestore_onode, bluestore_cache_onode); @@ -661,7 +663,7 @@ void BlueStore::GarbageCollector::process_protrusive_extents( } bExit = it == bi.last_lextent; ++it; - } while(!bExit); + } while (!bExit); } expected_for_release += blob_expected_for_release; expected_allocations += bi.expected_allocations; @@ -2019,6 +2021,28 @@ void BlueStore::ExtentMap::update(KeyValueDB::Transaction t, } } +bid_t BlueStore::ExtentMap::allocate_spanning_blob_id() +{ + if (spanning_blob_map.empty()) + return 0; + bid_t bid = spanning_blob_map.rbegin()->first + 1; + // bid is valid and available. + if (bid >= 0) + return bid; + // Find next unused bid; + bid = rand() % (numeric_limits::max() + 1); + const auto begin_bid = bid; + do { + if (!spanning_blob_map.count(bid)) + return bid; + else { + bid++; + if (bid < 0) bid = 0; + } + } while (bid != begin_bid); + assert(0 == "no available blob id"); +} + void BlueStore::ExtentMap::reshard( KeyValueDB *db, KeyValueDB::Transaction t) @@ -2208,12 +2232,6 @@ void BlueStore::ExtentMap::reshard( } else { shard_end = sp->offset; } - int bid; - if (spanning_blob_map.empty()) { - bid = 0; - } else { - bid = spanning_blob_map.rbegin()->first + 1; - } Extent dummy(needs_reshard_begin); for (auto e = extent_map.lower_bound(dummy); e != extent_map.end(); ++e) { if (e->logical_offset >= needs_reshard_end) { @@ -2267,7 +2285,8 @@ void BlueStore::ExtentMap::reshard( must_span = true; } if (must_span) { - b->id = bid++; + auto bid = allocate_spanning_blob_id(); + b->id = bid; spanning_blob_map[b->id] = b; dout(20) << __func__ << " adding spanning " << *b << dendl; } diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index de347ec9855..236ebba28ae 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -776,6 +776,7 @@ public: } void update(KeyValueDB::Transaction t, bool force); + decltype(BlueStore::Blob::id) allocate_spanning_blob_id(); void reshard( KeyValueDB *db, KeyValueDB::Transaction t); -- 2.39.5