Functions release/init_add_free/init_rm_free did not check its input against device size.
It is incorrect and had been a problem when you shrink device.
Signed-off-by: Adam Kupczyk <akupczyk@redhat.com>
Allocator::Allocator(const std::string& name,
int64_t _capacity,
int64_t _block_size)
- : capacity(_capacity), block_size(_block_size)
+ : device_size(_capacity), block_size(_block_size)
{
asok_hook = new SocketHook(this, name);
}
{
Allocator* alloc = nullptr;
if (type == "stupid") {
- alloc = new StupidAllocator(cct, name, size, block_size);
+ alloc = new StupidAllocator(cct, size, block_size, name);
} else if (type == "bitmap") {
alloc = new BitmapAllocator(cct, size, block_size, name);
} else if (type == "avl") {
const string& get_name() const;
int64_t get_capacity() const
{
- return capacity;
+ return device_size;
}
int64_t get_block_size() const
{
private:
class SocketHook;
SocketHook* asok_hook = nullptr;
-
- int64_t capacity = 0;
- int64_t block_size = 0;
+protected:
+ const int64_t device_size = 0;
+ const int64_t block_size = 0;
};
#endif
for (auto p = release_set.begin(); p != release_set.end(); ++p) {
const auto offset = p.get_start();
const auto length = p.get_len();
+ ceph_assert(offset + length <= uint64_t(num_total));
ldout(cct, 10) << __func__ << std::hex
<< " offset 0x" << offset
<< " length 0x" << length
void AvlAllocator::init_add_free(uint64_t offset, uint64_t length)
{
std::lock_guard l(lock);
+ ceph_assert(offset + length <= uint64_t(num_total));
ldout(cct, 10) << __func__ << std::hex
<< " offset 0x" << offset
<< " length 0x" << length
void AvlAllocator::init_rm_free(uint64_t offset, uint64_t length)
{
std::lock_guard l(lock);
+ ceph_assert(offset + length <= uint64_t(num_total));
ldout(cct, 10) << __func__ << std::hex
<< " offset 0x" << offset
<< " length 0x" << length
const interval_set<uint64_t>& release_set)
{
if (cct->_conf->subsys.should_gather<dout_subsys, 10>()) {
- for (auto r : release_set) {
- ldout(cct, 10) << __func__ << " 0x" << std::hex << r.first << "~" << r.second
- << std::dec << dendl;
+ for (auto& [offset, len] : release_set) {
+ ldout(cct, 10) << __func__ << " 0x" << std::hex << offset << "~" << len
+ << std::dec << dendl;
+ ceph_assert(offset + len <= (uint64_t)device_size);
}
}
_free_l2(release_set);
auto mas = get_min_alloc_size();
uint64_t offs = round_up_to(offset, mas);
uint64_t l = p2align(offset + length - offs, mas);
+ ceph_assert(offs + l <= (uint64_t)device_size);
_mark_free(offs, l);
ldout(cct, 10) << __func__ << " done" << dendl;
auto mas = get_min_alloc_size();
uint64_t offs = round_up_to(offset, mas);
uint64_t l = p2align(offset + length - offs, mas);
+ ceph_assert(offs + l <= (uint64_t)device_size);
_mark_allocated(offs, l);
ldout(cct, 10) << __func__ << " done" << dendl;
}
class BitmapAllocator : public Allocator,
public AllocatorLevel02<AllocatorLevel01Loose> {
CephContext* cct;
-
public:
BitmapAllocator(CephContext* _cct, int64_t capacity, int64_t alloc_unit, const std::string& name);
~BitmapAllocator() override
#define dout_prefix *_dout << "stupidalloc 0x" << this << " "
StupidAllocator::StupidAllocator(CephContext* cct,
- const std::string& name,
- int64_t _size,
- int64_t _block_size)
- : Allocator(name, _size, _block_size), cct(cct), num_free(0),
+ int64_t capacity,
+ int64_t _block_size,
+ const std::string& name)
+ : Allocator(name, capacity, _block_size),
+ cct(cct), num_free(0),
free(10)
{
ceph_assert(cct != nullptr);
- bdev_block_size = cct->_conf->bdev_block_size;
+ ceph_assert(block_size > 0);
}
StupidAllocator::~StupidAllocator()
unsigned StupidAllocator::_choose_bin(uint64_t orig_len)
{
- ceph_assert(bdev_block_size > 0);
- uint64_t len = orig_len / bdev_block_size;
+ uint64_t len = orig_len / block_size;
int bin = std::min((int)cbits(len), (int)free.size() - 1);
ldout(cct, 30) << __func__ << " len 0x" << std::hex << orig_len
<< std::dec << " -> " << bin << dendl;
ceph::mutex lock = ceph::make_mutex("StupidAllocator::lock");
int64_t num_free; ///< total bytes in freelist
- uint64_t bdev_block_size;
template <typename K, typename V> using allocator_t =
mempool::bluestore_alloc::pool_allocator<std::pair<const K, V>>;
public:
StupidAllocator(CephContext* cct,
- const std::string& name,
int64_t size,
- int64_t block_size);
+ int64_t block_size,
+ const std::string& name);
~StupidAllocator() override;
const char* get_type() const override
{