From 2ae7846977e6acd02d72634f63dfd5c4fa374b63 Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Mon, 3 Feb 2020 18:36:21 +0300 Subject: [PATCH] os/bluestore: fix unused 'tail' calculation. Fixes: https://tracker.ceph.com/issues/41901 Signed-off-by: Igor Fedotov (cherry picked from commit c91cc3a8d689995e8554c41c9b0f652d9a3458da) Conflicts: src/test/objectstore/store_test.cc - omitted test case "TEST_P(StoreTestSpecificAUSize, ReproBug41901Test)" from the backport, because nautilus does not have the "bluestore_debug_enforce_settings" option --- src/os/bluestore/BlueStore.cc | 6 ++++-- src/os/bluestore/bluestore_types.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 042aa6d97c7b0..f4181b6c754a4 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -12738,12 +12738,14 @@ int BlueStore::_do_alloc_write( } if (wi.mark_unused) { + ceph_assert(!dblob.is_compressed()); auto b_end = b_off + wi.bl.length(); if (b_off) { dblob.add_unused(0, b_off); } - if (b_end < wi.blob_length) { - dblob.add_unused(b_end, wi.blob_length - b_end); + uint64_t llen = dblob.get_logical_length(); + if (b_end < llen) { + dblob.add_unused(b_end, llen - b_end); } } diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h index d80df25168422..7f2393d240db3 100644 --- a/src/os/bluestore/bluestore_types.h +++ b/src/os/bluestore/bluestore_types.h @@ -631,6 +631,7 @@ public: if (!has_unused()) { return false; } + ceph_assert(!is_compressed()); uint64_t blob_len = get_logical_length(); ceph_assert((blob_len % (sizeof(unused)*8)) == 0); ceph_assert(offset + length <= blob_len); @@ -646,6 +647,7 @@ public: /// mark a range that has never been used void add_unused(uint64_t offset, uint64_t length) { + ceph_assert(!is_compressed()); uint64_t blob_len = get_logical_length(); ceph_assert((blob_len % (sizeof(unused)*8)) == 0); ceph_assert(offset + length <= blob_len); @@ -663,6 +665,7 @@ public: /// indicate that a range has (now) been used. void mark_used(uint64_t offset, uint64_t length) { if (has_unused()) { + ceph_assert(!is_compressed()); uint64_t blob_len = get_logical_length(); ceph_assert((blob_len % (sizeof(unused)*8)) == 0); ceph_assert(offset + length <= blob_len); -- 2.39.5