forked from vitalif/vitastor
Skip double allocs when reading journal
parent
f4769ba7c7
commit
ad9f619370
|
@ -37,6 +37,21 @@ allocator::~allocator()
|
|||
delete[] mask;
|
||||
}
|
||||
|
||||
bool allocator::get(uint64_t addr)
|
||||
{
|
||||
if (addr >= size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint64_t p2 = 1, offset = 0;
|
||||
while (p2 * 64 < size)
|
||||
{
|
||||
offset += p2;
|
||||
p2 = p2 * 64;
|
||||
}
|
||||
return ((mask[offset + addr/64] >> (addr % 64)) & 1);
|
||||
}
|
||||
|
||||
void allocator::set(uint64_t addr, bool value)
|
||||
{
|
||||
if (addr >= size)
|
||||
|
|
|
@ -16,6 +16,7 @@ class allocator
|
|||
public:
|
||||
allocator(uint64_t blocks);
|
||||
~allocator();
|
||||
bool get(uint64_t addr);
|
||||
void set(uint64_t addr, bool value);
|
||||
uint64_t find_free();
|
||||
uint64_t get_free_count();
|
||||
|
|
|
@ -402,6 +402,18 @@ resume_1:
|
|||
}
|
||||
}
|
||||
}
|
||||
for (auto ov: double_allocs)
|
||||
{
|
||||
auto dirty_it = bs->dirty_db.find(ov);
|
||||
if (dirty_it != bs->dirty_db.end() &&
|
||||
IS_BIG_WRITE(dirty_it->second.state) &&
|
||||
dirty_it->second.location == UINT64_MAX)
|
||||
{
|
||||
printf("Fatal error (bug): %lx:%lx v%lu big_write journal_entry was allocated over another object\n",
|
||||
dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
bs->flusher->mark_trim_possible();
|
||||
bs->journal.dirty_start = bs->journal.next_free;
|
||||
printf(
|
||||
|
@ -597,14 +609,23 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
|
|||
.oid = je->big_write.oid,
|
||||
.version = je->big_write.version,
|
||||
};
|
||||
bs->dirty_db.emplace(ov, (dirty_entry){
|
||||
auto dirty_it = bs->dirty_db.emplace(ov, (dirty_entry){
|
||||
.state = (BS_ST_BIG_WRITE | BS_ST_SYNCED),
|
||||
.flags = 0,
|
||||
.location = je->big_write.location,
|
||||
.offset = je->big_write.offset,
|
||||
.len = je->big_write.len,
|
||||
.journal_sector = proc_pos,
|
||||
});
|
||||
}).first;
|
||||
if (bs->data_alloc->get(je->big_write.location >> bs->block_order))
|
||||
{
|
||||
// This is probably a big_write that's already flushed and freed, but it may
|
||||
// also indicate a bug. So we remember such entries and recheck them afterwards
|
||||
dirty_it->second.location = UINT64_MAX;
|
||||
double_allocs.push_back(ov);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BLOCKSTORE_DEBUG
|
||||
printf(
|
||||
"Allocate block (journal) %lu: %lx:%lx v%lu\n",
|
||||
|
@ -613,6 +634,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
|
|||
);
|
||||
#endif
|
||||
bs->data_alloc->set(je->big_write.location >> bs->block_order, true);
|
||||
}
|
||||
bs->journal.used_sectors[proc_pos]++;
|
||||
#ifdef BLOCKSTORE_DEBUG
|
||||
printf(
|
||||
|
|
|
@ -36,6 +36,7 @@ class blockstore_init_journal
|
|||
bool started = false;
|
||||
uint64_t next_free;
|
||||
std::vector<bs_init_journal_done> done;
|
||||
std::vector<obj_ver_id> double_allocs;
|
||||
uint64_t journal_pos = 0;
|
||||
uint64_t continue_pos = 0;
|
||||
void *init_write_buf = NULL;
|
||||
|
|
|
@ -248,7 +248,8 @@ void blockstore_impl_t::erase_dirty(blockstore_dirty_db_t::iterator dirty_start,
|
|||
}
|
||||
while (1)
|
||||
{
|
||||
if (IS_BIG_WRITE(dirty_it->second.state) && dirty_it->second.location != clean_loc)
|
||||
if (IS_BIG_WRITE(dirty_it->second.state) && dirty_it->second.location != clean_loc &&
|
||||
dirty_it->second.location != UINT64_MAX)
|
||||
{
|
||||
#ifdef BLOCKSTORE_DEBUG
|
||||
printf("Free block %lu from %lx:%lx v%lu\n", dirty_it->second.location >> block_order,
|
||||
|
|
|
@ -20,7 +20,15 @@ void alloc_all(int size)
|
|||
{
|
||||
printf("incorrect block allocated: expected %d, got %lu\n", i, x);
|
||||
}
|
||||
if (a->get(x))
|
||||
{
|
||||
printf("not free before set at %d\n", i);
|
||||
}
|
||||
a->set(x, true);
|
||||
if (!a->get(x))
|
||||
{
|
||||
printf("free after set at %d\n", i);
|
||||
}
|
||||
}
|
||||
uint64_t x = a->find_free();
|
||||
if (x != UINT64_MAX)
|
||||
|
|
Loading…
Reference in New Issue