forked from vitalif/vitastor
Sadly we have to refcount dyn_data...
parent
a8ee391e05
commit
45e07d6294
|
@ -642,7 +642,8 @@ void journal_flusher_co::update_metadata_entry()
|
||||||
// Copy latest external bitmap/attributes
|
// Copy latest external bitmap/attributes
|
||||||
{
|
{
|
||||||
uint64_t dyn_size = bs->dsk.dirty_dyn_size(dirty_end->second.offset, dirty_end->second.len);
|
uint64_t dyn_size = bs->dsk.dirty_dyn_size(dirty_end->second.offset, dirty_end->second.len);
|
||||||
void *dyn_ptr = dyn_size > sizeof(void*) ? dirty_end->second.dyn_data : &dirty_end->second.dyn_data;
|
void *dyn_ptr = dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty_end->second.dyn_data+sizeof(int) : (uint8_t*)&dirty_end->second.dyn_data;
|
||||||
memcpy(new_clean_bitmap + bs->dsk.clean_entry_bitmap_size, dyn_ptr, bs->dsk.clean_entry_bitmap_size);
|
memcpy(new_clean_bitmap + bs->dsk.clean_entry_bitmap_size, dyn_ptr, bs->dsk.clean_entry_bitmap_size);
|
||||||
}
|
}
|
||||||
// Copy initial (big_write) data checksums
|
// Copy initial (big_write) data checksums
|
||||||
|
@ -955,7 +956,8 @@ void journal_flusher_co::scan_dirty()
|
||||||
// FIXME Remove this > sizeof(void*) inline perversion from everywhere.
|
// FIXME Remove this > sizeof(void*) inline perversion from everywhere.
|
||||||
// I think it doesn't matter but I couldn't stop myself from implementing it :)
|
// I think it doesn't matter but I couldn't stop myself from implementing it :)
|
||||||
uint64_t dyn_size = bs->dsk.dirty_dyn_size(dirty_it->second.offset, dirty_it->second.len);
|
uint64_t dyn_size = bs->dsk.dirty_dyn_size(dirty_it->second.offset, dirty_it->second.len);
|
||||||
uint8_t* dyn_from = (uint8_t*)(dyn_size > sizeof(void*) ? dirty_it->second.dyn_data : &dirty_it->second.dyn_data) +
|
uint8_t* dyn_from = (uint8_t*)(dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty_it->second.dyn_data+sizeof(int) : (uint8_t*)&dirty_it->second.dyn_data) +
|
||||||
bs->dsk.clean_entry_bitmap_size;
|
bs->dsk.clean_entry_bitmap_size;
|
||||||
it->csum_buf = dyn_from + (it->offset/bs->dsk.csum_block_size -
|
it->csum_buf = dyn_from + (it->offset/bs->dsk.csum_block_size -
|
||||||
dirty_it->second.offset/bs->dsk.csum_block_size) * (bs->dsk.data_csum_type & 0xFF);
|
dirty_it->second.offset/bs->dsk.csum_block_size) * (bs->dsk.data_csum_type & 0xFF);
|
||||||
|
@ -967,7 +969,7 @@ void journal_flusher_co::scan_dirty()
|
||||||
{
|
{
|
||||||
bs->pad_journal_read(v, *it, dirty_it->second.offset,
|
bs->pad_journal_read(v, *it, dirty_it->second.offset,
|
||||||
dirty_it->second.offset + dirty_it->second.len, dirty_it->second.location,
|
dirty_it->second.offset + dirty_it->second.len, dirty_it->second.location,
|
||||||
dyn_from, offset, submit_len, blk_begin, blk_end, blk_buf);
|
dyn_from, NULL, offset, submit_len, blk_begin, blk_end, blk_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -985,7 +987,7 @@ void journal_flusher_co::scan_dirty()
|
||||||
clean_bitmap_offset = dirty_it->second.offset;
|
clean_bitmap_offset = dirty_it->second.offset;
|
||||||
clean_bitmap_len = dirty_it->second.len;
|
clean_bitmap_len = dirty_it->second.len;
|
||||||
clean_init_dyn_ptr = bs->dsk.dirty_dyn_size(clean_bitmap_offset, clean_bitmap_len) > sizeof(void*)
|
clean_init_dyn_ptr = bs->dsk.dirty_dyn_size(clean_bitmap_offset, clean_bitmap_len) > sizeof(void*)
|
||||||
? (uint8_t*)dirty_it->second.dyn_data : (uint8_t*)&dirty_it->second.dyn_data;
|
? (uint8_t*)dirty_it->second.dyn_data+sizeof(int) : (uint8_t*)&dirty_it->second.dyn_data;
|
||||||
skip_copy = true;
|
skip_copy = true;
|
||||||
}
|
}
|
||||||
else if (IS_DELETE(dirty_it->second.state) && !skip_copy)
|
else if (IS_DELETE(dirty_it->second.state) && !skip_copy)
|
||||||
|
@ -1028,7 +1030,7 @@ void journal_flusher_co::scan_dirty()
|
||||||
uint8_t *bmp_ptr = bs->get_clean_entry_bitmap(old_clean_loc, 0);
|
uint8_t *bmp_ptr = bs->get_clean_entry_bitmap(old_clean_loc, 0);
|
||||||
uint64_t fulfilled = 0;
|
uint64_t fulfilled = 0;
|
||||||
read_to_fill_incomplete = bs->fill_partial_checksum_blocks(
|
read_to_fill_incomplete = bs->fill_partial_checksum_blocks(
|
||||||
v, fulfilled, bmp_ptr, false, NULL, v[0].offset/bs->dsk.csum_block_size * bs->dsk.csum_block_size,
|
v, fulfilled, bmp_ptr, NULL, false, NULL, v[0].offset/bs->dsk.csum_block_size * bs->dsk.csum_block_size,
|
||||||
((v[v.size()-1].offset+v[v.size()-1].len-1) / bs->dsk.csum_block_size + 1) * bs->dsk.csum_block_size
|
((v[v.size()-1].offset+v[v.size()-1].len-1) / bs->dsk.csum_block_size + 1) * bs->dsk.csum_block_size
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ struct copy_buffer_t
|
||||||
uint64_t journal_sector; // only for reads: sector+1 if used and !journal.inmemory, otherwise 0
|
uint64_t journal_sector; // only for reads: sector+1 if used and !journal.inmemory, otherwise 0
|
||||||
void *buf;
|
void *buf;
|
||||||
uint8_t *csum_buf;
|
uint8_t *csum_buf;
|
||||||
|
int *dyn_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct meta_sector_t
|
struct meta_sector_t
|
||||||
|
|
|
@ -331,14 +331,17 @@ class blockstore_impl_t
|
||||||
int dequeue_read(blockstore_op_t *read_op);
|
int dequeue_read(blockstore_op_t *read_op);
|
||||||
void find_holes(std::vector<copy_buffer_t> & read_vec, uint32_t item_start, uint32_t item_end,
|
void find_holes(std::vector<copy_buffer_t> & read_vec, uint32_t item_start, uint32_t item_end,
|
||||||
std::function<int(int, bool, uint32_t, uint32_t)> callback);
|
std::function<int(int, bool, uint32_t, uint32_t)> callback);
|
||||||
int fulfill_read(blockstore_op_t *read_op, uint64_t & fulfilled, uint32_t item_start, uint32_t item_end,
|
int fulfill_read(blockstore_op_t *read_op,
|
||||||
uint32_t item_state, uint64_t item_version, uint64_t item_location, uint64_t journal_sector, uint8_t *csum);
|
uint64_t &fulfilled, uint32_t item_start, uint32_t item_end,
|
||||||
|
uint32_t item_state, uint64_t item_version, uint64_t item_location,
|
||||||
|
uint64_t journal_sector, uint8_t *csum, int *dyn_data);
|
||||||
bool fulfill_clean_read(blockstore_op_t *read_op, uint64_t & fulfilled,
|
bool fulfill_clean_read(blockstore_op_t *read_op, uint64_t & fulfilled,
|
||||||
uint8_t *clean_entry_bitmap, uint32_t item_start, uint32_t item_end, uint64_t clean_loc, uint64_t clean_ver);
|
uint8_t *clean_entry_bitmap, int *dyn_data,
|
||||||
|
uint32_t item_start, uint32_t item_end, uint64_t clean_loc, uint64_t clean_ver);
|
||||||
int fill_partial_checksum_blocks(std::vector<copy_buffer_t> & rv, uint64_t & fulfilled,
|
int fill_partial_checksum_blocks(std::vector<copy_buffer_t> & rv, uint64_t & fulfilled,
|
||||||
uint8_t *clean_entry_bitmap, bool from_journal, uint8_t *read_buf, uint64_t read_offset, uint64_t read_end);
|
uint8_t *clean_entry_bitmap, int *dyn_data, bool from_journal, uint8_t *read_buf, uint64_t read_offset, uint64_t read_end);
|
||||||
int pad_journal_read(std::vector<copy_buffer_t> & rv, copy_buffer_t & cp,
|
int pad_journal_read(std::vector<copy_buffer_t> & rv, copy_buffer_t & cp,
|
||||||
uint64_t dirty_offset, uint64_t dirty_end, uint64_t dirty_loc, uint8_t *csum_ptr,
|
uint64_t dirty_offset, uint64_t dirty_end, uint64_t dirty_loc, uint8_t *csum_ptr, int *dyn_data,
|
||||||
uint64_t offset, uint64_t submit_len, uint64_t & blk_begin, uint64_t & blk_end, uint8_t* & blk_buf);
|
uint64_t offset, uint64_t submit_len, uint64_t & blk_begin, uint64_t & blk_end, uint8_t* & blk_buf);
|
||||||
bool read_range_fulfilled(std::vector<copy_buffer_t> & rv, uint64_t & fulfilled, uint8_t *read_buf,
|
bool read_range_fulfilled(std::vector<copy_buffer_t> & rv, uint64_t & fulfilled, uint8_t *read_buf,
|
||||||
uint8_t *clean_entry_bitmap, uint32_t item_start, uint32_t item_end);
|
uint8_t *clean_entry_bitmap, uint32_t item_start, uint32_t item_end);
|
||||||
|
|
|
@ -908,8 +908,9 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
|
||||||
// allocations for entry bitmaps. This can only be fixed by using
|
// allocations for entry bitmaps. This can only be fixed by using
|
||||||
// a patched map with dynamic entry size, but not the btree_map,
|
// a patched map with dynamic entry size, but not the btree_map,
|
||||||
// because it doesn't keep iterators valid all the time.
|
// because it doesn't keep iterators valid all the time.
|
||||||
dyn = malloc_or_die(dyn_size);
|
dyn = malloc_or_die(dyn_size+sizeof(int));
|
||||||
memcpy(dyn, dyn_from, dyn_size);
|
*((int*)dyn) = 1;
|
||||||
|
memcpy((uint8_t*)dyn+sizeof(int), dyn_from, dyn_size);
|
||||||
}
|
}
|
||||||
bs->dirty_db.emplace(ov, (dirty_entry){
|
bs->dirty_db.emplace(ov, (dirty_entry){
|
||||||
.state = (BS_ST_SMALL_WRITE | BS_ST_SYNCED),
|
.state = (BS_ST_SMALL_WRITE | BS_ST_SYNCED),
|
||||||
|
@ -996,8 +997,9 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
|
||||||
// allocations for entry bitmaps. This can only be fixed by using
|
// allocations for entry bitmaps. This can only be fixed by using
|
||||||
// a patched map with dynamic entry size, but not the btree_map,
|
// a patched map with dynamic entry size, but not the btree_map,
|
||||||
// because it doesn't keep iterators valid all the time.
|
// because it doesn't keep iterators valid all the time.
|
||||||
dyn = malloc_or_die(dyn_size);
|
dyn = malloc_or_die(dyn_size+sizeof(int));
|
||||||
memcpy(dyn, dyn_from, dyn_size);
|
*((int*)dyn) = 1;
|
||||||
|
memcpy((uint8_t*)dyn+sizeof(int), dyn_from, dyn_size);
|
||||||
}
|
}
|
||||||
auto dirty_it = 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),
|
.state = (BS_ST_BIG_WRITE | BS_ST_SYNCED),
|
||||||
|
|
|
@ -76,7 +76,7 @@ void blockstore_impl_t::find_holes(std::vector<copy_buffer_t> & read_vec,
|
||||||
int blockstore_impl_t::fulfill_read(blockstore_op_t *read_op,
|
int blockstore_impl_t::fulfill_read(blockstore_op_t *read_op,
|
||||||
uint64_t &fulfilled, uint32_t item_start, uint32_t item_end,
|
uint64_t &fulfilled, uint32_t item_start, uint32_t item_end,
|
||||||
uint32_t item_state, uint64_t item_version, uint64_t item_location,
|
uint32_t item_state, uint64_t item_version, uint64_t item_location,
|
||||||
uint64_t journal_sector, uint8_t *csum)
|
uint64_t journal_sector, uint8_t *csum, int *dyn_data)
|
||||||
{
|
{
|
||||||
int r = 1;
|
int r = 1;
|
||||||
if (item_start < read_op->offset + read_op->len && item_end > read_op->offset)
|
if (item_start < read_op->offset + read_op->len && item_end > read_op->offset)
|
||||||
|
@ -97,7 +97,12 @@ int blockstore_impl_t::fulfill_read(blockstore_op_t *read_op,
|
||||||
.disk_offset = item_location + start - item_start,
|
.disk_offset = item_location + start - item_start,
|
||||||
.journal_sector = (IS_JOURNAL(item_state) ? journal_sector : 0),
|
.journal_sector = (IS_JOURNAL(item_state) ? journal_sector : 0),
|
||||||
.csum_buf = !csum ? NULL : (csum + (start - item_start) / dsk.csum_block_size * (dsk.data_csum_type & 0xFF)),
|
.csum_buf = !csum ? NULL : (csum + (start - item_start) / dsk.csum_block_size * (dsk.data_csum_type & 0xFF)),
|
||||||
|
.dyn_data = dyn_data,
|
||||||
};
|
};
|
||||||
|
if (dyn_data)
|
||||||
|
{
|
||||||
|
(*dyn_data)++;
|
||||||
|
}
|
||||||
if (IS_BIG_WRITE(item_state))
|
if (IS_BIG_WRITE(item_state))
|
||||||
{
|
{
|
||||||
// If we don't track it then we may IN THEORY read another object's data:
|
// If we don't track it then we may IN THEORY read another object's data:
|
||||||
|
@ -109,7 +114,7 @@ int blockstore_impl_t::fulfill_read(blockstore_op_t *read_op,
|
||||||
if (!journal.inmemory && dsk.csum_block_size > dsk.bitmap_granularity && IS_JOURNAL(item_state) && !IS_DELETE(item_state))
|
if (!journal.inmemory && dsk.csum_block_size > dsk.bitmap_granularity && IS_JOURNAL(item_state) && !IS_DELETE(item_state))
|
||||||
{
|
{
|
||||||
int pad_state = pad_journal_read(rv, rv[pos], item_start, item_end, item_location,
|
int pad_state = pad_journal_read(rv, rv[pos], item_start, item_end, item_location,
|
||||||
csum, start, end-start, blk_begin, blk_end, blk_buf);
|
csum, dyn_data, start, end-start, blk_begin, blk_end, blk_buf);
|
||||||
if (pad_state == 2)
|
if (pad_state == 2)
|
||||||
return 1;
|
return 1;
|
||||||
else if (pad_state == 1)
|
else if (pad_state == 1)
|
||||||
|
@ -148,7 +153,7 @@ uint8_t* blockstore_impl_t::get_clean_entry_bitmap(uint64_t block_loc, int offse
|
||||||
}
|
}
|
||||||
|
|
||||||
int blockstore_impl_t::fill_partial_checksum_blocks(std::vector<copy_buffer_t> & rv, uint64_t & fulfilled,
|
int blockstore_impl_t::fill_partial_checksum_blocks(std::vector<copy_buffer_t> & rv, uint64_t & fulfilled,
|
||||||
uint8_t *clean_entry_bitmap, bool from_journal, uint8_t *read_buf, uint64_t read_offset, uint64_t read_end)
|
uint8_t *clean_entry_bitmap, int *dyn_data, bool from_journal, uint8_t *read_buf, uint64_t read_offset, uint64_t read_end)
|
||||||
{
|
{
|
||||||
if (read_end == read_offset)
|
if (read_end == read_offset)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -185,7 +190,12 @@ int blockstore_impl_t::fill_partial_checksum_blocks(std::vector<copy_buffer_t> &
|
||||||
.len = (end_block-start_block)*dsk.csum_block_size,
|
.len = (end_block-start_block)*dsk.csum_block_size,
|
||||||
// save clean_entry_bitmap if we're reading clean data from the journal
|
// save clean_entry_bitmap if we're reading clean data from the journal
|
||||||
.csum_buf = from_journal ? clean_entry_bitmap : NULL,
|
.csum_buf = from_journal ? clean_entry_bitmap : NULL,
|
||||||
|
.dyn_data = dyn_data,
|
||||||
});
|
});
|
||||||
|
if (dyn_data)
|
||||||
|
{
|
||||||
|
(*dyn_data)++;
|
||||||
|
}
|
||||||
start_block = end_block;
|
start_block = end_block;
|
||||||
required++;
|
required++;
|
||||||
}
|
}
|
||||||
|
@ -325,6 +335,7 @@ bool blockstore_impl_t::read_checksum_block(blockstore_op_t *op, int rv_pos, uin
|
||||||
.disk_offset = clean_loc + item_start,
|
.disk_offset = clean_loc + item_start,
|
||||||
.buf = (uint8_t*)buf,
|
.buf = (uint8_t*)buf,
|
||||||
.csum_buf = vi->csum_buf,
|
.csum_buf = vi->csum_buf,
|
||||||
|
.dyn_data = vi->dyn_data,
|
||||||
};
|
};
|
||||||
int submit_fd = (vi->copy_flags & COPY_BUF_JOURNAL ? dsk.journal_fd : dsk.data_fd);
|
int submit_fd = (vi->copy_flags & COPY_BUF_JOURNAL ? dsk.journal_fd : dsk.data_fd);
|
||||||
uint64_t submit_offset = (vi->copy_flags & COPY_BUF_JOURNAL ? journal.offset : dsk.data_offset);
|
uint64_t submit_offset = (vi->copy_flags & COPY_BUF_JOURNAL ? journal.offset : dsk.data_offset);
|
||||||
|
@ -402,7 +413,9 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
size_t dyn_size = dsk.dirty_dyn_size(dirty.offset, dirty.len);
|
size_t dyn_size = dsk.dirty_dyn_size(dirty.offset, dirty.len);
|
||||||
uint8_t *bmp_ptr = (uint8_t*)(dyn_size > sizeof(void*) ? dirty.dyn_data : &dirty.dyn_data);
|
int *dyn_data = (int*)(dsk.csum_block_size > 0 && dyn_size > sizeof(void*) ? dirty.dyn_data : NULL);
|
||||||
|
uint8_t *bmp_ptr = (dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty.dyn_data + sizeof(int) : (uint8_t*)&dirty.dyn_data);
|
||||||
if (!result_version)
|
if (!result_version)
|
||||||
{
|
{
|
||||||
result_version = dirty_it->first.version;
|
result_version = dirty_it->first.version;
|
||||||
|
@ -415,7 +428,8 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
|
||||||
if (!IS_JOURNAL(dirty.state))
|
if (!IS_JOURNAL(dirty.state))
|
||||||
{
|
{
|
||||||
// Read from data disk, possibly checking checksums
|
// Read from data disk, possibly checking checksums
|
||||||
if (!fulfill_clean_read(read_op, fulfilled, bmp_ptr, dirty.offset, dirty.offset+dirty.len, dirty.location, dirty_it->first.version))
|
if (!fulfill_clean_read(read_op, fulfilled, bmp_ptr, dyn_data,
|
||||||
|
dirty.offset, dirty.offset+dirty.len, dirty.location, dirty_it->first.version))
|
||||||
{
|
{
|
||||||
goto undo_read;
|
goto undo_read;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +439,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
|
||||||
// Copy from memory or read from journal, possibly checking checksums
|
// Copy from memory or read from journal, possibly checking checksums
|
||||||
if (!fulfill_read(read_op, fulfilled, dirty.offset, dirty.offset + dirty.len,
|
if (!fulfill_read(read_op, fulfilled, dirty.offset, dirty.offset + dirty.len,
|
||||||
dirty.state, dirty_it->first.version, dirty.location, dirty.journal_sector+1,
|
dirty.state, dirty_it->first.version, dirty.location, dirty.journal_sector+1,
|
||||||
journal.inmemory ? NULL : bmp_ptr+dsk.clean_entry_bitmap_size))
|
journal.inmemory ? NULL : bmp_ptr+dsk.clean_entry_bitmap_size, dyn_data))
|
||||||
{
|
{
|
||||||
goto undo_read;
|
goto undo_read;
|
||||||
}
|
}
|
||||||
|
@ -451,7 +465,8 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
|
||||||
}
|
}
|
||||||
if (fulfilled < read_op->len)
|
if (fulfilled < read_op->len)
|
||||||
{
|
{
|
||||||
if (!fulfill_clean_read(read_op, fulfilled, NULL, 0, dsk.data_block_size, clean_it->second.location, clean_it->second.version))
|
if (!fulfill_clean_read(read_op, fulfilled, NULL, NULL, 0, dsk.data_block_size,
|
||||||
|
clean_it->second.location, clean_it->second.version))
|
||||||
{
|
{
|
||||||
goto undo_read;
|
goto undo_read;
|
||||||
}
|
}
|
||||||
|
@ -501,6 +516,11 @@ undo_read:
|
||||||
free(vec.buf);
|
free(vec.buf);
|
||||||
vec.buf = NULL;
|
vec.buf = NULL;
|
||||||
}
|
}
|
||||||
|
if (vec.dyn_data && --(*vec.dyn_data) == 0) // refcount
|
||||||
|
{
|
||||||
|
free(vec.dyn_data);
|
||||||
|
vec.dyn_data = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv.clear();
|
rv.clear();
|
||||||
|
@ -509,7 +529,7 @@ undo_read:
|
||||||
|
|
||||||
int blockstore_impl_t::pad_journal_read(std::vector<copy_buffer_t> & rv, copy_buffer_t & cp,
|
int blockstore_impl_t::pad_journal_read(std::vector<copy_buffer_t> & rv, copy_buffer_t & cp,
|
||||||
// FIXME Passing dirty_entry& would be nicer
|
// FIXME Passing dirty_entry& would be nicer
|
||||||
uint64_t dirty_offset, uint64_t dirty_end, uint64_t dirty_loc, uint8_t *csum_ptr,
|
uint64_t dirty_offset, uint64_t dirty_end, uint64_t dirty_loc, uint8_t *csum_ptr, int *dyn_data,
|
||||||
uint64_t offset, uint64_t submit_len, uint64_t & blk_begin, uint64_t & blk_end, uint8_t* & blk_buf)
|
uint64_t offset, uint64_t submit_len, uint64_t & blk_begin, uint64_t & blk_end, uint8_t* & blk_buf)
|
||||||
{
|
{
|
||||||
if (offset % dsk.csum_block_size || submit_len % dsk.csum_block_size)
|
if (offset % dsk.csum_block_size || submit_len % dsk.csum_block_size)
|
||||||
|
@ -543,7 +563,12 @@ int blockstore_impl_t::pad_journal_read(std::vector<copy_buffer_t> & rv, copy_bu
|
||||||
.buf = blk_buf,
|
.buf = blk_buf,
|
||||||
.csum_buf = (csum_ptr + (blk_begin/dsk.csum_block_size -
|
.csum_buf = (csum_ptr + (blk_begin/dsk.csum_block_size -
|
||||||
dirty_offset/dsk.csum_block_size) * (dsk.data_csum_type & 0xFF)),
|
dirty_offset/dsk.csum_block_size) * (dsk.data_csum_type & 0xFF)),
|
||||||
|
.dyn_data = dyn_data,
|
||||||
});
|
});
|
||||||
|
if (dyn_data)
|
||||||
|
{
|
||||||
|
(*dyn_data)++;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,7 +577,7 @@ int blockstore_impl_t::pad_journal_read(std::vector<copy_buffer_t> & rv, copy_bu
|
||||||
}
|
}
|
||||||
|
|
||||||
bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t & fulfilled,
|
bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t & fulfilled,
|
||||||
uint8_t *clean_entry_bitmap, uint32_t item_start, uint32_t item_end, uint64_t clean_loc, uint64_t clean_ver)
|
uint8_t *clean_entry_bitmap, int *dyn_data, uint32_t item_start, uint32_t item_end, uint64_t clean_loc, uint64_t clean_ver)
|
||||||
{
|
{
|
||||||
bool from_journal = clean_entry_bitmap != NULL;
|
bool from_journal = clean_entry_bitmap != NULL;
|
||||||
if (!clean_entry_bitmap)
|
if (!clean_entry_bitmap)
|
||||||
|
@ -564,7 +589,7 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t &
|
||||||
if (dsk.csum_block_size > dsk.bitmap_granularity)
|
if (dsk.csum_block_size > dsk.bitmap_granularity)
|
||||||
{
|
{
|
||||||
auto & rv = PRIV(read_op)->read_vec;
|
auto & rv = PRIV(read_op)->read_vec;
|
||||||
int req = fill_partial_checksum_blocks(rv, fulfilled, clean_entry_bitmap, from_journal,
|
int req = fill_partial_checksum_blocks(rv, fulfilled, clean_entry_bitmap, dyn_data, from_journal,
|
||||||
(uint8_t*)read_op->buf, read_op->offset, read_op->offset+read_op->len);
|
(uint8_t*)read_op->buf, read_op->offset, read_op->offset+read_op->len);
|
||||||
for (int i = req; i > 0; i--)
|
for (int i = req; i > 0; i--)
|
||||||
{
|
{
|
||||||
|
@ -581,19 +606,19 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t &
|
||||||
uint8_t *csum = !dsk.csum_block_size ? 0 : (clean_entry_bitmap + dsk.clean_entry_bitmap_size +
|
uint8_t *csum = !dsk.csum_block_size ? 0 : (clean_entry_bitmap + dsk.clean_entry_bitmap_size +
|
||||||
item_start/dsk.csum_block_size*(dsk.data_csum_type & 0xFF));
|
item_start/dsk.csum_block_size*(dsk.data_csum_type & 0xFF));
|
||||||
if (!fulfill_read(read_op, fulfilled, item_start, item_end,
|
if (!fulfill_read(read_op, fulfilled, item_start, item_end,
|
||||||
(BS_ST_BIG_WRITE | BS_ST_STABLE), 0, clean_loc + item_start, 0, csum))
|
(BS_ST_BIG_WRITE | BS_ST_STABLE), 0, clean_loc + item_start, 0, csum, dyn_data))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (item_start > 0 && fulfilled < read_op->len)
|
if (item_start > 0 && fulfilled < read_op->len)
|
||||||
{
|
{
|
||||||
// fill with zeroes
|
// fill with zeroes
|
||||||
assert(fulfill_read(read_op, fulfilled, 0, item_start, (BS_ST_DELETE | BS_ST_STABLE), 0, 0, 0, NULL));
|
assert(fulfill_read(read_op, fulfilled, 0, item_start, (BS_ST_DELETE | BS_ST_STABLE), 0, 0, 0, NULL, NULL));
|
||||||
}
|
}
|
||||||
if (item_end < dsk.data_block_size && fulfilled < read_op->len)
|
if (item_end < dsk.data_block_size && fulfilled < read_op->len)
|
||||||
{
|
{
|
||||||
// fill with zeroes
|
// fill with zeroes
|
||||||
assert(fulfill_read(read_op, fulfilled, item_end, dsk.data_block_size, (BS_ST_DELETE | BS_ST_STABLE), 0, 0, 0, NULL));
|
assert(fulfill_read(read_op, fulfilled, item_end, dsk.data_block_size, (BS_ST_DELETE | BS_ST_STABLE), 0, 0, 0, NULL, NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -609,7 +634,7 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t &
|
||||||
{
|
{
|
||||||
// fill with zeroes
|
// fill with zeroes
|
||||||
assert(fulfill_read(read_op, fulfilled, bmp_start * dsk.bitmap_granularity,
|
assert(fulfill_read(read_op, fulfilled, bmp_start * dsk.bitmap_granularity,
|
||||||
bmp_end * dsk.bitmap_granularity, (BS_ST_DELETE | BS_ST_STABLE), 0, 0, 0, NULL));
|
bmp_end * dsk.bitmap_granularity, (BS_ST_DELETE | BS_ST_STABLE), 0, 0, 0, NULL, NULL));
|
||||||
}
|
}
|
||||||
bmp_start = bmp_end;
|
bmp_start = bmp_end;
|
||||||
while (clean_entry_bitmap[bmp_end >> 3] & (1 << (bmp_end & 0x7)) && bmp_end < bmp_size)
|
while (clean_entry_bitmap[bmp_end >> 3] & (1 << (bmp_end & 0x7)) && bmp_end < bmp_size)
|
||||||
|
@ -622,7 +647,7 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t &
|
||||||
bmp_start*dsk.bitmap_granularity/dsk.csum_block_size*(dsk.data_csum_type & 0xFF));
|
bmp_start*dsk.bitmap_granularity/dsk.csum_block_size*(dsk.data_csum_type & 0xFF));
|
||||||
if (!fulfill_read(read_op, fulfilled, bmp_start * dsk.bitmap_granularity,
|
if (!fulfill_read(read_op, fulfilled, bmp_start * dsk.bitmap_granularity,
|
||||||
bmp_end * dsk.bitmap_granularity, (BS_ST_BIG_WRITE | BS_ST_STABLE), 0,
|
bmp_end * dsk.bitmap_granularity, (BS_ST_BIG_WRITE | BS_ST_STABLE), 0,
|
||||||
clean_loc + bmp_start * dsk.bitmap_granularity, 0, csum))
|
clean_loc + bmp_start * dsk.bitmap_granularity, 0, csum, dyn_data))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -800,6 +825,11 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
|
||||||
}
|
}
|
||||||
free(rv[i].buf);
|
free(rv[i].buf);
|
||||||
rv[i].buf = NULL;
|
rv[i].buf = NULL;
|
||||||
|
if (rv[i].dyn_data && --(*rv[i].dyn_data) == 0) // refcount
|
||||||
|
{
|
||||||
|
free(rv[i].dyn_data);
|
||||||
|
rv[i].dyn_data = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -825,6 +855,11 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (vec.dyn_data && --(*vec.dyn_data) == 0) // refcount
|
||||||
|
{
|
||||||
|
free(vec.dyn_data);
|
||||||
|
vec.dyn_data = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,7 +952,8 @@ int blockstore_impl_t::read_bitmap(object_id oid, uint64_t target_version, void
|
||||||
if (bitmap)
|
if (bitmap)
|
||||||
{
|
{
|
||||||
size_t dyn_size = dsk.dirty_dyn_size(dirty_it->second.offset, dirty_it->second.len);
|
size_t dyn_size = dsk.dirty_dyn_size(dirty_it->second.offset, dirty_it->second.len);
|
||||||
void *dyn_ptr = (dyn_size > sizeof(void*) ? dirty_it->second.dyn_data : &dirty_it->second.dyn_data);
|
void *dyn_ptr = (dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty_it->second.dyn_data + sizeof(int) : (uint8_t*)&dirty_it->second.dyn_data);
|
||||||
memcpy(bitmap, dyn_ptr, dsk.clean_entry_bitmap_size);
|
memcpy(bitmap, dyn_ptr, dsk.clean_entry_bitmap_size);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -244,7 +244,8 @@ void blockstore_impl_t::free_dirty_dyn_data(dirty_entry & e)
|
||||||
size_t dyn_size = dsk.dirty_dyn_size(e.offset, e.len);
|
size_t dyn_size = dsk.dirty_dyn_size(e.offset, e.len);
|
||||||
if (dyn_size > sizeof(void*) &&
|
if (dyn_size > sizeof(void*) &&
|
||||||
(!journal.inmemory || e.dyn_data < journal.buffer ||
|
(!journal.inmemory || e.dyn_data < journal.buffer ||
|
||||||
e.dyn_data >= (uint8_t*)journal.buffer + journal.len))
|
e.dyn_data >= (uint8_t*)journal.buffer + journal.len) &&
|
||||||
|
--*((int*)e.dyn_data) == 0) // refcount
|
||||||
{
|
{
|
||||||
// dyn_data contains the bitmap and checksums
|
// dyn_data contains the bitmap and checksums
|
||||||
// free it if it doesn't refer to the in-memory journal
|
// free it if it doesn't refer to the in-memory journal
|
||||||
|
|
|
@ -132,7 +132,8 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op)
|
||||||
je->offset = dirty_entry.offset;
|
je->offset = dirty_entry.offset;
|
||||||
je->len = dirty_entry.len;
|
je->len = dirty_entry.len;
|
||||||
je->location = dirty_entry.location;
|
je->location = dirty_entry.location;
|
||||||
memcpy((void*)(je+1), (dyn_size > sizeof(void*) ? dirty_entry.dyn_data : &dirty_entry.dyn_data), dyn_size);
|
memcpy((void*)(je+1), (dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty_entry.dyn_data+sizeof(int) : (uint8_t*)&dirty_entry.dyn_data), dyn_size);
|
||||||
je->crc32 = je_crc32((journal_entry*)je);
|
je->crc32 = je_crc32((journal_entry*)je);
|
||||||
journal.crc32_last = je->crc32;
|
journal.crc32_last = je->crc32;
|
||||||
it++;
|
it++;
|
||||||
|
|
|
@ -16,9 +16,12 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
|
||||||
size_t dyn_size = dsk.dirty_dyn_size(op->offset, op->len);
|
size_t dyn_size = dsk.dirty_dyn_size(op->offset, op->len);
|
||||||
if (!is_del && dyn_size > sizeof(void*))
|
if (!is_del && dyn_size > sizeof(void*))
|
||||||
{
|
{
|
||||||
dyn = calloc_or_die(1, dyn_size);
|
// FIXME: Working with `dyn_data` has to be refactored somehow but I first have to decide how :)
|
||||||
|
// +sizeof(int) = refcount
|
||||||
|
dyn = calloc_or_die(1, dyn_size+sizeof(int));
|
||||||
|
*((int*)dyn) = 1;
|
||||||
}
|
}
|
||||||
uint8_t *dyn_ptr = (uint8_t*)(dyn_size > sizeof(void*) ? dyn : &dyn);
|
uint8_t *dyn_ptr = (uint8_t*)(dyn_size > sizeof(void*) ? dyn+sizeof(int) : &dyn);
|
||||||
uint64_t version = 1;
|
uint64_t version = 1;
|
||||||
if (dirty_db.size() > 0)
|
if (dirty_db.size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +43,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
|
||||||
if (!is_del && !deleted)
|
if (!is_del && !deleted)
|
||||||
{
|
{
|
||||||
void *dyn_from = dsk.dirty_dyn_size(dirty_it->second.offset, dirty_it->second.len) > sizeof(void*)
|
void *dyn_from = dsk.dirty_dyn_size(dirty_it->second.offset, dirty_it->second.len) > sizeof(void*)
|
||||||
? dirty_it->second.dyn_data : &dirty_it->second.dyn_data;
|
? (uint8_t*)dirty_it->second.dyn_data + sizeof(int) : (uint8_t*)&dirty_it->second.dyn_data;
|
||||||
memcpy(dyn_ptr, dyn_from, dsk.clean_entry_bitmap_size);
|
memcpy(dyn_ptr, dyn_from, dsk.clean_entry_bitmap_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +58,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
|
||||||
if (!is_del)
|
if (!is_del)
|
||||||
{
|
{
|
||||||
void *bmp_ptr = get_clean_entry_bitmap(clean_it->second.location, dsk.clean_entry_bitmap_size);
|
void *bmp_ptr = get_clean_entry_bitmap(clean_it->second.location, dsk.clean_entry_bitmap_size);
|
||||||
memcpy((dyn_size > sizeof(void*) ? dyn : &dyn), bmp_ptr, dsk.clean_entry_bitmap_size);
|
memcpy(dyn_ptr, bmp_ptr, dsk.clean_entry_bitmap_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -461,7 +464,8 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
|
||||||
je->len = op->len;
|
je->len = op->len;
|
||||||
je->data_offset = journal.next_free;
|
je->data_offset = journal.next_free;
|
||||||
je->crc32_data = dsk.csum_block_size ? 0 : crc32c(0, op->buf, op->len);
|
je->crc32_data = dsk.csum_block_size ? 0 : crc32c(0, op->buf, op->len);
|
||||||
memcpy((void*)(je+1), (dyn_size > sizeof(void*) ? dirty_it->second.dyn_data : &dirty_it->second.dyn_data), dyn_size);
|
memcpy((void*)(je+1), (dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty_it->second.dyn_data+sizeof(int) : (uint8_t*)&dirty_it->second.dyn_data), dyn_size);
|
||||||
je->crc32 = je_crc32((journal_entry*)je);
|
je->crc32 = je_crc32((journal_entry*)je);
|
||||||
journal.crc32_last = je->crc32;
|
journal.crc32_last = je->crc32;
|
||||||
if (immediate_commit != IMMEDIATE_NONE)
|
if (immediate_commit != IMMEDIATE_NONE)
|
||||||
|
@ -556,7 +560,8 @@ resume_2:
|
||||||
je->offset = op->offset;
|
je->offset = op->offset;
|
||||||
je->len = op->len;
|
je->len = op->len;
|
||||||
je->location = dirty_it->second.location;
|
je->location = dirty_it->second.location;
|
||||||
memcpy((void*)(je+1), (dyn_size > sizeof(void*) ? dirty_it->second.dyn_data : &dirty_it->second.dyn_data), dyn_size);
|
memcpy((void*)(je+1), (dyn_size > sizeof(void*)
|
||||||
|
? (uint8_t*)dirty_it->second.dyn_data+sizeof(int) : (uint8_t*)&dirty_it->second.dyn_data), dyn_size);
|
||||||
je->crc32 = je_crc32((journal_entry*)je);
|
je->crc32 = je_crc32((journal_entry*)je);
|
||||||
journal.crc32_last = je->crc32;
|
journal.crc32_last = je->crc32;
|
||||||
prepare_journal_sector_write(journal.cur_sector, op);
|
prepare_journal_sector_write(journal.cur_sector, op);
|
||||||
|
|
Loading…
Reference in New Issue