From 45e07d62945c0e26dcb7d72b4c362c103538fa02 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 10 Jun 2023 19:17:02 +0300 Subject: [PATCH] Sadly we have to refcount dyn_data... --- src/blockstore_flush.cpp | 12 ++++--- src/blockstore_flush.h | 1 + src/blockstore_impl.h | 13 ++++--- src/blockstore_init.cpp | 10 +++--- src/blockstore_read.cpp | 68 ++++++++++++++++++++++++++++--------- src/blockstore_rollback.cpp | 3 +- src/blockstore_sync.cpp | 3 +- src/blockstore_write.cpp | 17 ++++++---- 8 files changed, 89 insertions(+), 38 deletions(-) diff --git a/src/blockstore_flush.cpp b/src/blockstore_flush.cpp index 6407fb0a..fc60cb92 100644 --- a/src/blockstore_flush.cpp +++ b/src/blockstore_flush.cpp @@ -642,7 +642,8 @@ void journal_flusher_co::update_metadata_entry() // Copy latest external bitmap/attributes { 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); } // 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. // 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); - 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; 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); @@ -967,7 +969,7 @@ void journal_flusher_co::scan_dirty() { bs->pad_journal_read(v, *it, dirty_it->second.offset, 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_len = dirty_it->second.len; 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; } 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); uint64_t fulfilled = 0; 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 ); } diff --git a/src/blockstore_flush.h b/src/blockstore_flush.h index 57f0cbd2..db73228c 100644 --- a/src/blockstore_flush.h +++ b/src/blockstore_flush.h @@ -14,6 +14,7 @@ struct copy_buffer_t uint64_t journal_sector; // only for reads: sector+1 if used and !journal.inmemory, otherwise 0 void *buf; uint8_t *csum_buf; + int *dyn_data; }; struct meta_sector_t diff --git a/src/blockstore_impl.h b/src/blockstore_impl.h index 643e6137..b56a4ea0 100644 --- a/src/blockstore_impl.h +++ b/src/blockstore_impl.h @@ -331,14 +331,17 @@ class blockstore_impl_t int dequeue_read(blockstore_op_t *read_op); void find_holes(std::vector & read_vec, uint32_t item_start, uint32_t item_end, std::function callback); - int fulfill_read(blockstore_op_t *read_op, 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 fulfill_read(blockstore_op_t *read_op, + 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, - 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 & 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 & 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); bool read_range_fulfilled(std::vector & rv, uint64_t & fulfilled, uint8_t *read_buf, uint8_t *clean_entry_bitmap, uint32_t item_start, uint32_t item_end); diff --git a/src/blockstore_init.cpp b/src/blockstore_init.cpp index e9a872f6..7cfea298 100644 --- a/src/blockstore_init.cpp +++ b/src/blockstore_init.cpp @@ -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 // a patched map with dynamic entry size, but not the btree_map, // because it doesn't keep iterators valid all the time. - dyn = malloc_or_die(dyn_size); - memcpy(dyn, dyn_from, dyn_size); + dyn = malloc_or_die(dyn_size+sizeof(int)); + *((int*)dyn) = 1; + memcpy((uint8_t*)dyn+sizeof(int), dyn_from, dyn_size); } bs->dirty_db.emplace(ov, (dirty_entry){ .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 // a patched map with dynamic entry size, but not the btree_map, // because it doesn't keep iterators valid all the time. - dyn = malloc_or_die(dyn_size); - memcpy(dyn, dyn_from, dyn_size); + dyn = malloc_or_die(dyn_size+sizeof(int)); + *((int*)dyn) = 1; + memcpy((uint8_t*)dyn+sizeof(int), dyn_from, dyn_size); } auto dirty_it = bs->dirty_db.emplace(ov, (dirty_entry){ .state = (BS_ST_BIG_WRITE | BS_ST_SYNCED), diff --git a/src/blockstore_read.cpp b/src/blockstore_read.cpp index 6a675c62..1c3927b1 100644 --- a/src/blockstore_read.cpp +++ b/src/blockstore_read.cpp @@ -76,7 +76,7 @@ void blockstore_impl_t::find_holes(std::vector & read_vec, int blockstore_impl_t::fulfill_read(blockstore_op_t *read_op, 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) + uint64_t journal_sector, uint8_t *csum, int *dyn_data) { int r = 1; 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, .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)), + .dyn_data = dyn_data, }; + if (dyn_data) + { + (*dyn_data)++; + } if (IS_BIG_WRITE(item_state)) { // 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)) { 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) return 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 & 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) return 0; @@ -185,7 +190,12 @@ int blockstore_impl_t::fill_partial_checksum_blocks(std::vector & .len = (end_block-start_block)*dsk.csum_block_size, // save clean_entry_bitmap if we're reading clean data from the journal .csum_buf = from_journal ? clean_entry_bitmap : NULL, + .dyn_data = dyn_data, }); + if (dyn_data) + { + (*dyn_data)++; + } start_block = end_block; 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, .buf = (uint8_t*)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); 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; } 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) { 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)) { // 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; } @@ -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 if (!fulfill_read(read_op, fulfilled, dirty.offset, dirty.offset + dirty.len, 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; } @@ -451,7 +465,8 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op) } 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; } @@ -501,6 +516,11 @@ undo_read: free(vec.buf); vec.buf = NULL; } + if (vec.dyn_data && --(*vec.dyn_data) == 0) // refcount + { + free(vec.dyn_data); + vec.dyn_data = NULL; + } } } rv.clear(); @@ -509,7 +529,7 @@ undo_read: int blockstore_impl_t::pad_journal_read(std::vector & rv, copy_buffer_t & cp, // 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) { 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 & rv, copy_bu .buf = blk_buf, .csum_buf = (csum_ptr + (blk_begin/dsk.csum_block_size - dirty_offset/dsk.csum_block_size) * (dsk.data_csum_type & 0xFF)), + .dyn_data = dyn_data, }); + if (dyn_data) + { + (*dyn_data)++; + } return 1; } } @@ -552,7 +577,7 @@ int blockstore_impl_t::pad_journal_read(std::vector & rv, copy_bu } 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; 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) { 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); 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 + item_start/dsk.csum_block_size*(dsk.data_csum_type & 0xFF)); 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; } if (item_start > 0 && fulfilled < read_op->len) { // 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) { // 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 @@ -609,7 +634,7 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t & { // fill with zeroes 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; 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)); if (!fulfill_read(read_op, fulfilled, bmp_start * dsk.bitmap_granularity, 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; } @@ -800,6 +825,11 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op } free(rv[i].buf); 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 @@ -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) { 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); } return 0; diff --git a/src/blockstore_rollback.cpp b/src/blockstore_rollback.cpp index 59fb3343..243186ad 100644 --- a/src/blockstore_rollback.cpp +++ b/src/blockstore_rollback.cpp @@ -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); if (dyn_size > sizeof(void*) && (!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 // free it if it doesn't refer to the in-memory journal diff --git a/src/blockstore_sync.cpp b/src/blockstore_sync.cpp index 6fb86f51..c8bb5243 100644 --- a/src/blockstore_sync.cpp +++ b/src/blockstore_sync.cpp @@ -132,7 +132,8 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op) je->offset = dirty_entry.offset; je->len = dirty_entry.len; 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); journal.crc32_last = je->crc32; it++; diff --git a/src/blockstore_write.cpp b/src/blockstore_write.cpp index 1fc019db..142c0685 100644 --- a/src/blockstore_write.cpp +++ b/src/blockstore_write.cpp @@ -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); 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; if (dirty_db.size() > 0) { @@ -40,7 +43,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op) if (!is_del && !deleted) { 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); } } @@ -55,7 +58,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op) if (!is_del) { 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 @@ -461,7 +464,8 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op) je->len = op->len; je->data_offset = journal.next_free; 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); journal.crc32_last = je->crc32; if (immediate_commit != IMMEDIATE_NONE) @@ -556,7 +560,8 @@ resume_2: je->offset = op->offset; je->len = op->len; 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); journal.crc32_last = je->crc32; prepare_journal_sector_write(journal.cur_sector, op);