From: Yin Congmin Date: Tue, 6 Jul 2021 11:35:42 +0000 (+0800) Subject: librbd/cache/pwl/ssd: add layout version control X-Git-Tag: v16.2.7~45^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=15f62d23d1a7540820ebf57bb7b41b504fdfa356;p=ceph.git librbd/cache/pwl/ssd: add layout version control Signed-off-by: Yin Congmin (cherry picked from commit dc566a3cd30d91ecbe87cb049df5e9462a526b6d) --- diff --git a/src/librbd/cache/pwl/Types.h b/src/librbd/cache/pwl/Types.h index 1d6c169b53b5a..06d5b52bdb0c7 100644 --- a/src/librbd/cache/pwl/Types.h +++ b/src/librbd/cache/pwl/Types.h @@ -177,7 +177,8 @@ const uint64_t MIN_POOL_SIZE = DEFAULT_POOL_SIZE; const uint64_t POOL_SIZE_ALIGN = 1 << 20; constexpr double USABLE_SIZE = (7.0 / 10); const uint64_t BLOCK_ALLOC_OVERHEAD_BYTES = 16; -const uint8_t RWL_POOL_VERSION = 1; +const uint8_t RWL_LAYOUT_VERSION = 1; +const uint8_t SSD_LAYOUT_VERSION = 1; const uint64_t MAX_LOG_ENTRIES = (1024 * 1024); const double AGGRESSIVE_RETIRE_HIGH_WATER = 0.75; const double RETIRE_HIGH_WATER = 0.50; @@ -282,7 +283,7 @@ struct WriteLogPoolRoot { #ifdef WITH_RBD_RWL union { struct { - uint8_t layout_version; /* Version of this structure (RWL_POOL_VERSION) */ + uint8_t layout_version; /* Version of this structure (RWL_LAYOUT_VERSION) */ }; uint64_t _u64; } header; diff --git a/src/librbd/cache/pwl/rwl/WriteLog.cc b/src/librbd/cache/pwl/rwl/WriteLog.cc index 25612197862e5..f5cc9747ae5dd 100644 --- a/src/librbd/cache/pwl/rwl/WriteLog.cc +++ b/src/librbd/cache/pwl/rwl/WriteLog.cc @@ -300,7 +300,7 @@ bool WriteLog::initialize_pool(Context *on_finish, pwl::DeferredContexts &lat m_first_valid_entry = 0; TX_BEGIN(m_log_pool) { TX_ADD(pool_root); - D_RW(pool_root)->header.layout_version = RWL_POOL_VERSION; + D_RW(pool_root)->header.layout_version = RWL_LAYOUT_VERSION; D_RW(pool_root)->log_entries = TX_ZALLOC(struct WriteLogCacheEntry, sizeof(struct WriteLogCacheEntry) * num_small_writes); @@ -333,11 +333,11 @@ bool WriteLog::initialize_pool(Context *on_finish, pwl::DeferredContexts &lat return false; } pool_root = POBJ_ROOT(m_log_pool, struct WriteLogPoolRoot); - if (D_RO(pool_root)->header.layout_version != RWL_POOL_VERSION) { + if (D_RO(pool_root)->header.layout_version != RWL_LAYOUT_VERSION) { // TODO: will handle upgrading version in the future lderr(cct) << "Pool layout version is " << D_RO(pool_root)->header.layout_version - << " expected " << RWL_POOL_VERSION << dendl; + << " expected " << RWL_LAYOUT_VERSION << dendl; on_finish->complete(-EINVAL); return false; } diff --git a/src/librbd/cache/pwl/ssd/WriteLog.cc b/src/librbd/cache/pwl/ssd/WriteLog.cc index 9541827bf2630..c2042a239c0e9 100644 --- a/src/librbd/cache/pwl/ssd/WriteLog.cc +++ b/src/librbd/cache/pwl/ssd/WriteLog.cc @@ -132,6 +132,7 @@ template bool WriteLog::initialize_pool(Context *on_finish, pwl::DeferredContexts &later) { int r; + CephContext *cct = m_image_ctx.cct; ceph_assert(ceph_mutex_is_locked_by_me(m_lock)); if (access(this->m_log_pool_name.c_str(), F_OK) != 0) { @@ -176,6 +177,7 @@ bool WriteLog::initialize_pool(Context *on_finish, m_first_valid_entry = DATA_RING_BUFFER_OFFSET; auto new_root = std::make_shared(pool_root); + new_root->layout_version = SSD_LAYOUT_VERSION; new_root->pool_size = this->m_log_pool_size; new_root->flushed_sync_gen = this->m_flushed_sync_gen; new_root->block_size = MIN_WRITE_ALLOC_SSD_SIZE; @@ -186,8 +188,8 @@ bool WriteLog::initialize_pool(Context *on_finish, r = update_pool_root_sync(new_root); if (r != 0) { - lderr(m_image_ctx.cct) << "failed to initialize pool (" - << this->m_log_pool_name << ")" << dendl; + lderr(cct) << "failed to initialize pool (" + << this->m_log_pool_name << ")" << dendl; bdev->close(); delete bdev; on_finish->complete(r); @@ -200,11 +202,57 @@ bool WriteLog::initialize_pool(Context *on_finish, on_finish->complete(r); return false; } + + bufferlist bl; + SuperBlock superblock; + ::IOContext ioctx(cct, nullptr); + r = bdev->read(0, MIN_WRITE_ALLOC_SSD_SIZE, &bl, &ioctx, false); + if (r < 0) { + lderr(cct) << "Read ssd cache superblock failed " << dendl; + goto error_handle; + } + auto p = bl.cbegin(); + decode(superblock, p); + pool_root = superblock.root; + ldout(cct, 1) << "Decoded root: pool_size=" << pool_root.pool_size + << " first_valid_entry=" << pool_root.first_valid_entry + << " first_free_entry=" << pool_root.first_free_entry + << " flushed_sync_gen=" << pool_root.flushed_sync_gen + << dendl; + ceph_assert(is_valid_pool_root(pool_root)); + if (pool_root.layout_version != SSD_LAYOUT_VERSION) { + lderr(cct) << "Pool layout version is " + << pool_root.layout_version + << " expected " << SSD_LAYOUT_VERSION + << dendl; + goto error_handle; + } + if (pool_root.block_size != MIN_WRITE_ALLOC_SSD_SIZE) { + lderr(cct) << "Pool block size is " << pool_root.block_size + << " expected " << MIN_WRITE_ALLOC_SSD_SIZE + << dendl; + goto error_handle; + } + + this->m_log_pool_size = pool_root.pool_size; + this->m_flushed_sync_gen = pool_root.flushed_sync_gen; + this->m_first_valid_entry = pool_root.first_valid_entry; + this->m_first_free_entry = pool_root.first_free_entry; + this->m_bytes_allocated_cap = this->m_log_pool_size - + DATA_RING_BUFFER_OFFSET - + MIN_WRITE_ALLOC_SSD_SIZE; + load_existing_entries(later); m_cache_state->clean = this->m_dirty_log_entries.empty(); m_cache_state->empty = m_log_entries.empty(); } return true; + +error_handle: + bdev->close(); + delete bdev; + on_finish->complete(-EINVAL); + return false; } template @@ -234,33 +282,8 @@ void WriteLog::remove_pool_file() { template void WriteLog::load_existing_entries(pwl::DeferredContexts &later) { - bufferlist bl; CephContext *cct = m_image_ctx.cct; - ::IOContext ioctx(cct, nullptr); - bdev->read(0, MIN_WRITE_ALLOC_SSD_SIZE, &bl, &ioctx, false); - SuperBlock superblock; - - auto p = bl.cbegin(); - decode(superblock, p); - - pool_root = superblock.root; - ldout(cct, 1) << "Decoded root: pool_size=" << pool_root.pool_size - << " first_valid_entry=" << pool_root.first_valid_entry - << " first_free_entry=" << pool_root.first_free_entry - << " flushed_sync_gen=" << pool_root.flushed_sync_gen - << dendl; - ceph_assert(is_valid_pool_root(pool_root)); - - this->m_log_pool_size = pool_root.pool_size; - this->m_flushed_sync_gen = pool_root.flushed_sync_gen; - this->m_first_valid_entry = pool_root.first_valid_entry; - this->m_first_free_entry = pool_root.first_free_entry; - - this->m_bytes_allocated_cap = this->m_log_pool_size - - DATA_RING_BUFFER_OFFSET - MIN_WRITE_ALLOC_SSD_SIZE; - std::map> sync_point_entries; - std::map missing_sync_points; // Iterate through the log_entries and append all the write_bytes