Skip to content

Commit

Permalink
Fix potential crashes during commit with alternate region sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
cberner committed Jun 12, 2023
1 parent 566cba8 commit 076bdda
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 19 deletions.
5 changes: 4 additions & 1 deletion src/tree_store/page_store/buddy_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,13 @@ impl BuddyAllocator {
// Align to the highest order possible
while processed_pages < self.len() {
let order: u8 = processed_pages.trailing_zeros().try_into().unwrap();
if order >= self.max_order {
break;
}
let order_size = 2u32.pow(order.into());
let page = processed_pages / order_size;
debug_assert_eq!(processed_pages % order_size, 0);
if order >= self.max_order || processed_pages + order_size > self.len() {
if processed_pages + order_size > self.len() {
break;
}
self.record_alloc_inner(page, order);
Expand Down
21 changes: 21 additions & 0 deletions src/tree_store/page_store/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub(super) struct RegionLayout {

impl RegionLayout {
pub(super) fn new(num_pages: u32, header_pages: u32, page_size: u32) -> Self {
assert!(num_pages > 0);
Self {
num_pages,
header_pages,
Expand Down Expand Up @@ -101,6 +102,26 @@ impl DatabaseLayout {
}
}

pub(super) fn reduce_last_region(&mut self, pages: u32) {
if let Some(ref mut trailing) = self.trailing_partial_region {
assert!(pages <= trailing.num_pages);
trailing.num_pages -= pages;
if trailing.num_pages == 0 {
self.trailing_partial_region = None;
}
} else {
self.num_full_regions -= 1;
let full_layout = self.full_region_layout;
if full_layout.num_pages > pages {
self.trailing_partial_region = Some(RegionLayout::new(
full_layout.num_pages - pages,
full_layout.header_pages,
full_layout.page_size,
));
}
}
}

pub(super) fn recalculate(
file_len: u64,
region_header_pages_u32: u32,
Expand Down
23 changes: 5 additions & 18 deletions src/tree_store/page_store/page_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,35 +896,22 @@ impl TransactionalMemory {
fn try_shrink(&self, state: &mut InMemoryState) -> Result<bool> {
let layout = state.header.layout();
let last_region_index = layout.num_regions() - 1;
let last_region = layout.region_layout(last_region_index);
let last_allocator = state.get_region(last_region_index);
let trailing_free = last_allocator.trailing_free_pages();
let last_allocator_len = last_allocator.len();
if trailing_free < last_allocator_len / 2 {
return Ok(false);
}
let reduce_to_pages = if layout.num_regions() > 1 && trailing_free == last_allocator_len {
0
let reduce_by = if layout.num_regions() > 1 && trailing_free == last_allocator_len {
trailing_free
} else {
max(MIN_USABLE_PAGES, last_allocator_len - trailing_free / 2)
trailing_free / 2
};

let new_usable_bytes = if reduce_to_pages == 0 {
layout.usable_bytes() - last_region.usable_bytes()
} else {
layout.usable_bytes()
- ((last_allocator_len - reduce_to_pages) as u64)
* (state.header.page_size() as u64)
};

let new_layout = DatabaseLayout::calculate(
new_usable_bytes,
state.header.layout().full_region_layout().num_pages(),
self.page_size,
);
let mut new_layout = layout;
new_layout.reduce_last_region(reduce_by);
state.allocators.resize_to(new_layout);
assert!(new_layout.len() <= layout.len());

state.header.set_layout(new_layout);

Ok(true)
Expand Down

0 comments on commit 076bdda

Please sign in to comment.