Skip to content

Commit 15fa1d7

Browse files
authored
Merge pull request ceph#54992 from ifed01/wip-ifed-enforce-min-alloc-size
os/bluestore: introduce bluestore_debug_enforce_min_alloc_size config Reviewed-by: Pere Diaz Bou <[email protected]>
2 parents 45e4495 + a019458 commit 15fa1d7

File tree

5 files changed

+62
-13
lines changed

5 files changed

+62
-13
lines changed

src/common/options/global.yaml.in

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4406,6 +4406,21 @@ options:
44064406
flags:
44074407
- create
44084408
with_legacy: true
4409+
- name: bluestore_debug_enforce_min_alloc_size
4410+
type: uint
4411+
level: dev
4412+
desc: Enforces specific min_alloc size usages
4413+
long_desc: This overrides actual min_alloc_size value persisted on mkfs
4414+
(and originally obtained from bluestore_min_alloc_size) and permits to
4415+
use arbitrary value for this value. Intended primarily for dev/debug
4416+
purposes and should be used with care and deep understanding of potential
4417+
consequences, e.g. data corruption.
4418+
default: 0
4419+
see_also:
4420+
- bluestore_min_alloc_size
4421+
flags:
4422+
- startup
4423+
with_legacy: true
44094424
- name: bluestore_use_optimal_io_size_for_min_alloc_size
44104425
type: bool
44114426
level: advanced

src/os/bluestore/BitmapFreelistManager.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,3 +610,19 @@ void BitmapFreelistManager::get_meta(
610610
res->emplace_back("bfm_bytes_per_block", stringify(bytes_per_block));
611611
res->emplace_back("bfm_blocks_per_key", stringify(blocks_per_key));
612612
}
613+
614+
bool BitmapFreelistManager::validate(uint64_t min_alloc_size) const
615+
{
616+
bool ret = true;
617+
auto my_alloc_size = get_alloc_size();
618+
ceph_assert(my_alloc_size);
619+
ceph_assert(min_alloc_size);
620+
if (!is_null_manager() &&
621+
((min_alloc_size < my_alloc_size) || (min_alloc_size % my_alloc_size))) {
622+
derr << __func__ << " inconsistent alloc units:" << std::hex
623+
<< "0x" << get_alloc_size() << " vs. 0x" << min_alloc_size
624+
<< std::dec << dendl;
625+
ret = false;
626+
}
627+
return ret;
628+
}

src/os/bluestore/BitmapFreelistManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class BitmapFreelistManager : public FreelistManager {
9494
}
9595
void get_meta(uint64_t target_size,
9696
std::vector<std::pair<std::string, std::string>>*) const override;
97+
98+
bool validate(uint64_t min_alloc_size) const override;
9799
};
98100

99101
#endif

src/os/bluestore/BlueStore.cc

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6791,6 +6791,14 @@ int BlueStore::_open_fm(KeyValueDB::Transaction t,
67916791
return r;
67926792
}
67936793
}
6794+
dout(1) << __func__ << " effective freelist_type = " << freelist_type << std::hex
6795+
<< ", freelist_alloc_size = 0x" << fm->get_alloc_size()
6796+
<< ", min_alloc_size = 0x" << min_alloc_size
6797+
<< std::dec << dendl;
6798+
if (!fm->validate(min_alloc_size)) {
6799+
derr << __func__ << " freelist validation failed, unable to proceed." << dendl;
6800+
ceph_assert(false);
6801+
}
67946802
// if space size tracked by free list manager is that higher than actual
67956803
// dev size one can hit out-of-space allocation which will result
67966804
// in data loss and/or assertions
@@ -13116,20 +13124,26 @@ int BlueStore::_open_super_meta()
1311613124
}
1311713125

1311813126
{
13119-
bufferlist bl;
13120-
db->get(PREFIX_SUPER, "min_alloc_size", &bl);
13121-
auto p = bl.cbegin();
13122-
try {
13123-
uint64_t val;
13124-
decode(val, p);
13125-
min_alloc_size = val;
13126-
min_alloc_size_order = std::countr_zero(val);
13127-
min_alloc_size_mask = min_alloc_size - 1;
13127+
if(cct->_conf->bluestore_debug_enforce_min_alloc_size == 0) {
13128+
bufferlist bl;
13129+
db->get(PREFIX_SUPER, "min_alloc_size", &bl);
13130+
auto p = bl.cbegin();
13131+
try {
13132+
uint64_t val;
13133+
decode(val, p);
13134+
min_alloc_size = val;
13135+
min_alloc_size_order = std::countr_zero(val);
13136+
min_alloc_size_mask = min_alloc_size - 1;
1312813137

13129-
ceph_assert(min_alloc_size == 1u << min_alloc_size_order);
13130-
} catch (ceph::buffer::error& e) {
13131-
derr << __func__ << " unable to read min_alloc_size" << dendl;
13132-
return -EIO;
13138+
ceph_assert(min_alloc_size == 1u << min_alloc_size_order);
13139+
} catch (ceph::buffer::error& e) {
13140+
derr << __func__ << " unable to read min_alloc_size" << dendl;
13141+
return -EIO;
13142+
}
13143+
} else {
13144+
min_alloc_size = cct->_conf->bluestore_debug_enforce_min_alloc_size;
13145+
min_alloc_size_order = std::countr_zero(min_alloc_size);
13146+
min_alloc_size_mask = min_alloc_size - 1;
1313313147
}
1313413148
dout(1) << __func__ << " min_alloc_size 0x" << std::hex << min_alloc_size
1313513149
<< std::dec << dendl;

src/os/bluestore/FreelistManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class FreelistManager {
5252
virtual void get_meta(uint64_t target_size,
5353
std::vector<std::pair<std::string, std::string>>*) const = 0;
5454

55+
virtual bool validate(uint64_t min_alloc_size) const = 0;
56+
5557
void set_null_manager() {
5658
null_manager = true;
5759
}

0 commit comments

Comments
 (0)