flags:
- create
with_legacy: true
+- name: bluestore_debug_enforce_min_alloc_size
+ type: uint
+ level: dev
+ desc: Enforces specific min_alloc size usages
+ long_desc: This overrides actual min_alloc_size value persisted on mkfs
+ (and originally obtained from bluestore_min_alloc_size) and permits to
+ use arbitrary value for this value. Intended primarily for dev/debug
+ purposes and should be used with care and deep understanding of potential
+ consequences, e.g. data corruption.
+ default: 0
+ see_also:
+ - bluestore_min_alloc_size
+ flags:
+ - startup
+ with_legacy: true
- name: bluestore_use_optimal_io_size_for_min_alloc_size
type: bool
level: advanced
res->emplace_back("bfm_bytes_per_block", stringify(bytes_per_block));
res->emplace_back("bfm_blocks_per_key", stringify(blocks_per_key));
}
+
+bool BitmapFreelistManager::validate(uint64_t min_alloc_size) const
+{
+ bool ret = true;
+ auto my_alloc_size = get_alloc_size();
+ ceph_assert(my_alloc_size);
+ ceph_assert(min_alloc_size);
+ if (!is_null_manager() &&
+ ((min_alloc_size < my_alloc_size) || (min_alloc_size % my_alloc_size))) {
+ derr << __func__ << " inconsistent alloc units:" << std::hex
+ << "0x" << get_alloc_size() << " vs. 0x" << min_alloc_size
+ << std::dec << dendl;
+ ret = false;
+ }
+ return ret;
+}
return r;
}
}
+ dout(1) << __func__ << " effective freelist_type = " << freelist_type << std::hex
+ << ", freelist_alloc_size = 0x" << fm->get_alloc_size()
+ << ", min_alloc_size = 0x" << min_alloc_size
+ << std::dec << dendl;
+ if (!fm->validate(min_alloc_size)) {
+ derr << __func__ << " freelist validation failed, unable to proceed." << dendl;
+ ceph_assert(false);
+ }
// if space size tracked by free list manager is that higher than actual
// dev size one can hit out-of-space allocation which will result
// in data loss and/or assertions
}
{
- bufferlist bl;
- db->get(PREFIX_SUPER, "min_alloc_size", &bl);
- auto p = bl.cbegin();
- try {
- uint64_t val;
- decode(val, p);
- min_alloc_size = val;
- min_alloc_size_order = std::countr_zero(val);
- min_alloc_size_mask = min_alloc_size - 1;
+ if(cct->_conf->bluestore_debug_enforce_min_alloc_size == 0) {
+ bufferlist bl;
+ db->get(PREFIX_SUPER, "min_alloc_size", &bl);
+ auto p = bl.cbegin();
+ try {
+ uint64_t val;
+ decode(val, p);
+ min_alloc_size = val;
+ min_alloc_size_order = std::countr_zero(val);
+ min_alloc_size_mask = min_alloc_size - 1;
- ceph_assert(min_alloc_size == 1u << min_alloc_size_order);
- } catch (ceph::buffer::error& e) {
- derr << __func__ << " unable to read min_alloc_size" << dendl;
- return -EIO;
+ ceph_assert(min_alloc_size == 1u << min_alloc_size_order);
+ } catch (ceph::buffer::error& e) {
+ derr << __func__ << " unable to read min_alloc_size" << dendl;
+ return -EIO;
+ }
+ } else {
+ min_alloc_size = cct->_conf->bluestore_debug_enforce_min_alloc_size;
+ min_alloc_size_order = std::countr_zero(min_alloc_size);
+ min_alloc_size_mask = min_alloc_size - 1;
}
dout(1) << __func__ << " min_alloc_size 0x" << std::hex << min_alloc_size
<< std::dec << dendl;