diff --git a/src/allocator.cpp b/src/allocator.cpp index 2893a56b7..06ec6cf84 100644 --- a/src/allocator.cpp +++ b/src/allocator.cpp @@ -142,3 +142,35 @@ uint64_t allocator::get_free_count() { return free; } + +void bitmap_set(void *bitmap, uint64_t start, uint64_t len, uint64_t bitmap_granularity) +{ + if (start == 0) + { + if (len == 32*bitmap_granularity) + { + *((uint32_t*)bitmap) = UINT32_MAX; + return; + } + else if (len == 64*bitmap_granularity) + { + *((uint64_t*)bitmap) = UINT64_MAX; + return; + } + } + unsigned bit_start = start / bitmap_granularity; + unsigned bit_end = ((start + len) + bitmap_granularity - 1) / bitmap_granularity; + while (bit_start < bit_end) + { + if (!(bit_start & 7) && bit_end >= bit_start+8) + { + ((uint8_t*)bitmap)[bit_start / 8] = UINT8_MAX; + bit_start += 8; + } + else + { + ((uint8_t*)bitmap)[bit_start / 8] |= 1 << (bit_start % 8); + bit_start++; + } + } +} diff --git a/src/allocator.h b/src/allocator.h index 1bc5d4441..1a759297f 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -21,3 +21,5 @@ public: uint64_t find_free(); uint64_t get_free_count(); }; + +void bitmap_set(void *bitmap, uint64_t start, uint64_t len, uint64_t bitmap_granularity); diff --git a/src/blockstore_flush.cpp b/src/blockstore_flush.cpp index b3920a7f8..ee573954d 100644 --- a/src/blockstore_flush.cpp +++ b/src/blockstore_flush.cpp @@ -432,14 +432,14 @@ resume_1: if (clean_init_bitmap) { memset(new_clean_bitmap, 0, bs->clean_entry_bitmap_size); - bitmap_set(new_clean_bitmap, clean_bitmap_offset, clean_bitmap_len); + bitmap_set(new_clean_bitmap, clean_bitmap_offset, clean_bitmap_len, bs->bitmap_granularity); } } for (it = v.begin(); it != v.end(); it++) { if (new_clean_bitmap) { - bitmap_set(new_clean_bitmap, it->offset, it->len); + bitmap_set(new_clean_bitmap, it->offset, it->len, bs->bitmap_granularity); } await_sqe(4); data->iov = (struct iovec){ it->buf, (size_t)it->len }; @@ -885,35 +885,3 @@ bool journal_flusher_co::fsync_batch(bool fsync_meta, int wait_base) } return true; } - -void journal_flusher_co::bitmap_set(void *bitmap, uint64_t start, uint64_t len) -{ - if (start == 0) - { - if (len == 32*bs->bitmap_granularity) - { - *((uint32_t*)bitmap) = UINT32_MAX; - return; - } - else if (len == 64*bs->bitmap_granularity) - { - *((uint64_t*)bitmap) = UINT64_MAX; - return; - } - } - unsigned bit_start = start / bs->bitmap_granularity; - unsigned bit_end = ((start + len) + bs->bitmap_granularity - 1) / bs->bitmap_granularity; - while (bit_start < bit_end) - { - if (!(bit_start & 7) && bit_end >= bit_start+8) - { - ((uint8_t*)bitmap)[bit_start / 8] = UINT8_MAX; - bit_start += 8; - } - else - { - ((uint8_t*)bitmap)[bit_start / 8] |= 1 << (bit_start % 8); - bit_start++; - } - } -} diff --git a/src/blockstore_flush.h b/src/blockstore_flush.h index 0bf4ebe05..cf8d2e1d0 100644 --- a/src/blockstore_flush.h +++ b/src/blockstore_flush.h @@ -69,7 +69,6 @@ class journal_flusher_co bool modify_meta_read(uint64_t meta_loc, flusher_meta_write_t &wr, int wait_base); void update_clean_db(); bool fsync_batch(bool fsync_meta, int wait_base); - void bitmap_set(void *bitmap, uint64_t start, uint64_t len); public: journal_flusher_co(); bool loop(); diff --git a/src/osd_primary.cpp b/src/osd_primary.cpp index d62434ca7..1bcf60df9 100644 --- a/src/osd_primary.cpp +++ b/src/osd_primary.cpp @@ -115,7 +115,7 @@ void osd_t::continue_primary_read(osd_op_t *cur_op) if (pg.state == PG_ACTIVE || op_data->scheme == POOL_SCHEME_REPLICATED) { // Fast happy-path - cur_op->buf = alloc_read_buffer(op_data->stripes, op_data->pg_data_size, 0); + cur_op->buf = alloc_read_buffer(op_data->stripes, op_data->pg_data_size, 0, 0); submit_primary_subops(SUBMIT_READ, op_data->target_ver, (op_data->scheme == POOL_SCHEME_REPLICATED ? pg.pg_size : op_data->pg_data_size), pg.cur_set.data(), cur_op); op_data->st = 1; @@ -133,7 +133,7 @@ void osd_t::continue_primary_read(osd_op_t *cur_op) op_data->pg_size = pg.pg_size; op_data->scheme = pg.scheme; op_data->degraded = 1; - cur_op->buf = alloc_read_buffer(op_data->stripes, pg.pg_size, 0); + cur_op->buf = alloc_read_buffer(op_data->stripes, pg.pg_size, 0, 0); submit_primary_subops(SUBMIT_READ, op_data->target_ver, pg.pg_size, cur_set, cur_op); op_data->st = 1; } @@ -152,11 +152,11 @@ resume_2: osd_rmw_stripe_t *stripes = op_data->stripes; if (op_data->scheme == POOL_SCHEME_XOR) { - reconstruct_stripes_xor(stripes, op_data->pg_size); + reconstruct_stripes_xor(stripes, op_data->pg_size, 0); } else if (op_data->scheme == POOL_SCHEME_JERASURE) { - reconstruct_stripes_jerasure(stripes, op_data->pg_size, op_data->pg_data_size); + reconstruct_stripes_jerasure(stripes, op_data->pg_size, op_data->pg_data_size, 0); } for (int role = 0; role < op_data->pg_size; role++) { diff --git a/src/osd_primary_write.cpp b/src/osd_primary_write.cpp index d40257cf5..e984b2191 100644 --- a/src/osd_primary_write.cpp +++ b/src/osd_primary_write.cpp @@ -77,7 +77,7 @@ resume_1: else { cur_op->rmw_buf = calc_rmw(cur_op->buf, op_data->stripes, op_data->prev_set, - pg.pg_size, op_data->pg_data_size, pg.pg_cursize, pg.cur_set.data(), bs_block_size); + pg.pg_size, op_data->pg_data_size, pg.pg_cursize, pg.cur_set.data(), bs_block_size, 0); if (!cur_op->rmw_buf) { // Refuse partial overwrite of an incomplete object @@ -120,11 +120,11 @@ resume_3: // Recover missing stripes, calculate parity if (pg.scheme == POOL_SCHEME_XOR) { - calc_rmw_parity_xor(op_data->stripes, pg.pg_size, op_data->prev_set, pg.cur_set.data(), bs_block_size); + calc_rmw_parity_xor(op_data->stripes, pg.pg_size, op_data->prev_set, pg.cur_set.data(), bs_block_size, 0); } else if (pg.scheme == POOL_SCHEME_JERASURE) { - calc_rmw_parity_jerasure(op_data->stripes, pg.pg_size, op_data->pg_data_size, op_data->prev_set, pg.cur_set.data(), bs_block_size); + calc_rmw_parity_jerasure(op_data->stripes, pg.pg_size, op_data->pg_data_size, op_data->prev_set, pg.cur_set.data(), bs_block_size, 0); } } // Send writes diff --git a/src/osd_rmw.cpp b/src/osd_rmw.cpp index acde6abca..02ef23e48 100644 --- a/src/osd_rmw.cpp +++ b/src/osd_rmw.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "allocator.h" #include "xor.h" #include "osd_rmw.h" #include "malloc_or_die.h" @@ -81,7 +82,7 @@ void split_stripes(uint64_t pg_minsize, uint32_t bs_block_size, uint32_t start, } } -void reconstruct_stripes_xor(osd_rmw_stripe_t *stripes, int pg_size) +void reconstruct_stripes_xor(osd_rmw_stripe_t *stripes, int pg_size, uint32_t bitmap_size) { for (int role = 0; role < pg_size; role++) { @@ -106,6 +107,7 @@ void reconstruct_stripes_xor(osd_rmw_stripe_t *stripes, int pg_size) stripes[other].read_buf + (stripes[role].read_start - stripes[other].read_start), stripes[role].read_buf, stripes[role].read_end - stripes[role].read_start ); + memxor(stripes[prev].bmp_buf, stripes[other].bmp_buf, stripes[role].bmp_buf, bitmap_size); prev = -1; } else @@ -116,6 +118,7 @@ void reconstruct_stripes_xor(osd_rmw_stripe_t *stripes, int pg_size) stripes[other].read_buf + (stripes[role].read_start - stripes[other].read_start), stripes[role].read_buf, stripes[role].read_end - stripes[role].read_start ); + memxor(stripes[role].bmp_buf, stripes[other].bmp_buf, stripes[role].bmp_buf, bitmap_size); } } } @@ -230,7 +233,7 @@ int* get_jerasure_decoding_matrix(osd_rmw_stripe_t *stripes, int pg_size, int pg return dec_it->second; } -void reconstruct_stripes_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize) +void reconstruct_stripes_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize, uint32_t bitmap_size) { int *dm_ids = get_jerasure_decoding_matrix(stripes, pg_size, pg_minsize); if (!dm_ids) @@ -257,6 +260,18 @@ void reconstruct_stripes_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg pg_minsize, OSD_JERASURE_W, decoding_matrix+(role*pg_minsize), dm_ids, role, data_ptrs, data_ptrs+pg_minsize, stripes[role].read_end - stripes[role].read_start ); + for (int other = 0; other < pg_size; other++) + { + if (stripes[other].read_end != 0 && !stripes[other].missing) + { + data_ptrs[other] = (char*)(stripes[other].bmp_buf); + } + } + data_ptrs[role] = (char*)stripes[role].bmp_buf; + jerasure_matrix_dotprod( + pg_minsize, OSD_JERASURE_W, decoding_matrix+(role*pg_minsize), dm_ids, role, + data_ptrs, data_ptrs+pg_minsize, bitmap_size + ); } } } @@ -294,7 +309,7 @@ int extend_missing_stripes(osd_rmw_stripe_t *stripes, osd_num_t *osd_set, int pg return 0; } -void* alloc_read_buffer(osd_rmw_stripe_t *stripes, int read_pg_size, uint64_t add_size) +void* alloc_read_buffer(osd_rmw_stripe_t *stripes, int read_pg_size, uint64_t add_size, uint32_t bitmap_size) { // Calculate buffer size uint64_t buf_size = add_size; @@ -306,7 +321,7 @@ void* alloc_read_buffer(osd_rmw_stripe_t *stripes, int read_pg_size, uint64_t ad } } // Allocate buffer - void *buf = memalign_or_die(MEM_ALIGNMENT, buf_size); + void *buf = memalign_or_die(MEM_ALIGNMENT, buf_size + bitmap_size*read_pg_size); uint64_t buf_pos = add_size; for (int role = 0; role < read_pg_size; role++) { @@ -316,11 +331,21 @@ void* alloc_read_buffer(osd_rmw_stripe_t *stripes, int read_pg_size, uint64_t ad buf_pos += stripes[role].read_end - stripes[role].read_start; } } + // Bitmaps are allocated in the end so data buffers remain aligned + if (bitmap_size > 0) + { + for (int role = 0; role < read_pg_size; role++) + { + stripes[role].bmp_buf = buf + buf_pos; + buf_pos += bitmap_size; + } + } return buf; } void* calc_rmw(void *request_buf, osd_rmw_stripe_t *stripes, uint64_t *read_osd_set, - uint64_t pg_size, uint64_t pg_minsize, uint64_t pg_cursize, uint64_t *write_osd_set, uint64_t chunk_size) + uint64_t pg_size, uint64_t pg_minsize, uint64_t pg_cursize, uint64_t *write_osd_set, + uint64_t chunk_size, uint32_t bitmap_size) { // Generic parity modification (read-modify-write) algorithm // Read -> Reconstruct missing chunks -> Calc parity chunks -> Write @@ -420,7 +445,7 @@ void* calc_rmw(void *request_buf, osd_rmw_stripe_t *stripes, uint64_t *read_osd_ } } // Allocate read buffers - void *rmw_buf = alloc_read_buffer(stripes, pg_size, (write_parity ? pg_size-pg_minsize : 0) * (end - start)); + void *rmw_buf = alloc_read_buffer(stripes, pg_size, (write_parity ? pg_size-pg_minsize : 0) * (end - start), bitmap_size); // Position write buffers uint64_t buf_pos = 0, in_pos = 0; for (int role = 0; role < pg_size; role++) @@ -521,11 +546,12 @@ static void xor_multiple_buffers(buf_len_t *xor1, int n1, buf_len_t *xor2, int n } static void calc_rmw_parity_copy_mod(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize, - uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size, uint32_t &start, uint32_t &end) + uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size, uint32_t bitmap_granularity, + uint32_t &start, uint32_t &end) { if (write_osd_set[pg_minsize] != 0 || write_osd_set != read_osd_set) { - // Required for the next two if()s + // start & end are required for calc_rmw_parity for (int role = 0; role < pg_minsize; role++) { if (stripes[role].req_end != 0) @@ -543,6 +569,20 @@ static void calc_rmw_parity_copy_mod(osd_rmw_stripe_t *stripes, int pg_size, int } } } + // Set bitmap bits accordingly + if (bitmap_granularity > 0) + { + for (int role = 0; role < pg_minsize; role++) + { + if (stripes[role].req_end != 0) + { + bitmap_set( + stripes[role].bmp_buf, stripes[role].req_start, + stripes[role].req_end-stripes[role].req_start, bitmap_granularity + ); + } + } + } if (write_osd_set != read_osd_set) { for (int role = 0; role < pg_minsize; role++) @@ -603,12 +643,14 @@ static void calc_rmw_parity_copy_parity(osd_rmw_stripe_t *stripes, int pg_size, #endif } -void calc_rmw_parity_xor(osd_rmw_stripe_t *stripes, int pg_size, uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size) +void calc_rmw_parity_xor(osd_rmw_stripe_t *stripes, int pg_size, uint64_t *read_osd_set, uint64_t *write_osd_set, + uint32_t chunk_size, uint32_t bitmap_size) { + uint32_t bitmap_granularity = bitmap_size > 0 ? chunk_size / bitmap_size / 8 : 0; int pg_minsize = pg_size-1; - reconstruct_stripes_xor(stripes, pg_size); + reconstruct_stripes_xor(stripes, pg_size, bitmap_size); uint32_t start = 0, end = 0; - calc_rmw_parity_copy_mod(stripes, pg_size, pg_minsize, read_osd_set, write_osd_set, chunk_size, start, end); + calc_rmw_parity_copy_mod(stripes, pg_size, pg_minsize, read_osd_set, write_osd_set, chunk_size, bitmap_granularity, start, end); if (write_osd_set[pg_minsize] != 0 && end != 0) { // Calculate new parity (XOR k+1) @@ -626,9 +668,11 @@ void calc_rmw_parity_xor(osd_rmw_stripe_t *stripes, int pg_size, uint64_t *read_ if (prev == -1) { xor1[n1++] = { .buf = stripes[parity].write_buf, .len = end-start }; + memxor(stripes[parity].bmp_buf, stripes[other].bmp_buf, stripes[parity].bmp_buf, bitmap_size); } else { + memxor(stripes[prev].bmp_buf, stripes[other].bmp_buf, stripes[parity].bmp_buf, bitmap_size); get_old_new_buffers(stripes[prev], start, end, xor1, n1); prev = -1; } @@ -641,12 +685,13 @@ void calc_rmw_parity_xor(osd_rmw_stripe_t *stripes, int pg_size, uint64_t *read_ } void calc_rmw_parity_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize, - uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size) + uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size, uint32_t bitmap_size) { + uint32_t bitmap_granularity = bitmap_size > 0 ? chunk_size / bitmap_size / 8 : 0; reed_sol_matrix_t *matrix = get_jerasure_matrix(pg_size, pg_minsize); - reconstruct_stripes_jerasure(stripes, pg_size, pg_minsize); + reconstruct_stripes_jerasure(stripes, pg_size, pg_minsize, bitmap_size); uint32_t start = 0, end = 0; - calc_rmw_parity_copy_mod(stripes, pg_size, pg_minsize, read_osd_set, write_osd_set, chunk_size, start, end); + calc_rmw_parity_copy_mod(stripes, pg_size, pg_minsize, read_osd_set, write_osd_set, chunk_size, bitmap_granularity, start, end); if (end != 0) { int i; @@ -701,6 +746,14 @@ void calc_rmw_parity_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_min ); pos = next_end; } + for (int i = 0; i < pg_size; i++) + { + data_ptrs[i] = stripes[i].bmp_buf; + } + jerasure_matrix_encode( + pg_minsize, pg_size-pg_minsize, OSD_JERASURE_W, matrix->data, + (char**)data_ptrs, (char**)data_ptrs+pg_minsize, bitmap_size + ); } } calc_rmw_parity_copy_parity(stripes, pg_size, pg_minsize, read_osd_set, write_osd_set, chunk_size, start, end); diff --git a/src/osd_rmw.h b/src/osd_rmw.h index 5f0e30ef7..931c5cb19 100644 --- a/src/osd_rmw.h +++ b/src/osd_rmw.h @@ -20,6 +20,7 @@ struct buf_len_t struct osd_rmw_stripe_t { void *read_buf, *write_buf; + void *bmp_buf; uint32_t req_start, req_end; uint32_t read_start, read_end; uint32_t write_start, write_end; @@ -30,20 +31,22 @@ struct osd_rmw_stripe_t void split_stripes(uint64_t pg_minsize, uint32_t bs_block_size, uint32_t start, uint32_t len, osd_rmw_stripe_t *stripes); -void reconstruct_stripes_xor(osd_rmw_stripe_t *stripes, int pg_size); +void reconstruct_stripes_xor(osd_rmw_stripe_t *stripes, int pg_size, uint32_t bitmap_size); int extend_missing_stripes(osd_rmw_stripe_t *stripes, osd_num_t *osd_set, int pg_minsize, int pg_size); -void* alloc_read_buffer(osd_rmw_stripe_t *stripes, int read_pg_size, uint64_t add_size); +void* alloc_read_buffer(osd_rmw_stripe_t *stripes, int read_pg_size, uint64_t add_size, uint32_t bitmap_size); void* calc_rmw(void *request_buf, osd_rmw_stripe_t *stripes, uint64_t *read_osd_set, - uint64_t pg_size, uint64_t pg_minsize, uint64_t pg_cursize, uint64_t *write_osd_set, uint64_t chunk_size); + uint64_t pg_size, uint64_t pg_minsize, uint64_t pg_cursize, uint64_t *write_osd_set, + uint64_t chunk_size, uint32_t bitmap_size); -void calc_rmw_parity_xor(osd_rmw_stripe_t *stripes, int pg_size, uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size); +void calc_rmw_parity_xor(osd_rmw_stripe_t *stripes, int pg_size, uint64_t *read_osd_set, uint64_t *write_osd_set, + uint32_t chunk_size, uint32_t bitmap_size); void use_jerasure(int pg_size, int pg_minsize, bool use); -void reconstruct_stripes_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize); +void reconstruct_stripes_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize, uint32_t bitmap_size); void calc_rmw_parity_jerasure(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize, - uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size); + uint64_t *read_osd_set, uint64_t *write_osd_set, uint32_t chunk_size, uint32_t bitmap_size); diff --git a/src/osd_rmw_test.cpp b/src/osd_rmw_test.cpp index 79e840422..64b278c71 100644 --- a/src/osd_rmw_test.cpp +++ b/src/osd_rmw_test.cpp @@ -126,12 +126,13 @@ void test1() void test4() { + const uint32_t bmp = 4; osd_num_t osd_set[3] = { 1, 0, 3 }; osd_rmw_stripe_t stripes[3] = { 0 }; // Test 4.1 split_stripes(2, 128*1024, 128*1024-4096, 8192, stripes); void* write_buf = malloc(8192); - void* rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, osd_set, 128*1024); + void* rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, osd_set, 128*1024, bmp); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 4096 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 4096 && stripes[2].read_end == 128*1024); @@ -149,7 +150,13 @@ void test4() set_pattern(stripes[0].read_buf, 128*1024, PATTERN1); // old data set_pattern(stripes[1].read_buf, 128*1024-4096, UINT64_MAX); // didn't read it, it's missing set_pattern(stripes[2].read_buf, 128*1024-4096, 0); // old parity = 0 - calc_rmw_parity_xor(stripes, 3, osd_set, osd_set, 128*1024); + memset(stripes[0].bmp_buf, 0, bmp); + memset(stripes[1].bmp_buf, 0, bmp); + memset(stripes[2].bmp_buf, 0, bmp); + calc_rmw_parity_xor(stripes, 3, osd_set, osd_set, 128*1024, bmp); + assert(*(uint32_t*)stripes[0].bmp_buf == 0x80000000); + assert(*(uint32_t*)stripes[1].bmp_buf == 0x00000001); + assert(*(uint32_t*)stripes[2].bmp_buf == 0x80000001); // XOR check_pattern(stripes[2].write_buf, 4096, PATTERN0^PATTERN1); // new parity check_pattern(stripes[2].write_buf+4096, 128*1024-4096*2, 0); // new parity check_pattern(stripes[2].write_buf+128*1024-4096, 4096, PATTERN0^PATTERN1); // new parity @@ -181,7 +188,7 @@ void test5() assert(stripes[2].req_end == 0); // Test 5.2 void *write_buf = malloc(64*1024*3); - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, osd_set, 128*1024, 0); assert(stripes[0].read_start == 64*1024 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 64*1024 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 64*1024 && stripes[2].read_end == 128*1024); @@ -218,7 +225,7 @@ void test6() // Test 6.1 split_stripes(2, 128*1024, 0, 64*1024*3, stripes); void *write_buf = malloc(64*1024*3); - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, osd_set, 128*1024, 0); assert(stripes[0].read_end == 0); assert(stripes[1].read_start == 64*1024 && stripes[1].read_end == 128*1024); assert(stripes[2].read_end == 0); @@ -261,7 +268,7 @@ void test7() // Test 7.1 split_stripes(2, 128*1024, 128*1024-4096, 8192, stripes); void *write_buf = malloc(8192); - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, write_osd_set, 128*1024, 0); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 0 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 0 && stripes[2].read_end == 128*1024); @@ -279,7 +286,7 @@ void test7() set_pattern(stripes[0].read_buf, 128*1024, PATTERN1); // old data set_pattern(stripes[1].read_buf, 128*1024, UINT64_MAX); // didn't read it, it's missing set_pattern(stripes[2].read_buf, 128*1024, 0); // old parity = 0 - calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 128*1024-4096 && stripes[0].write_end == 128*1024); assert(stripes[1].write_start == 0 && stripes[1].write_end == 128*1024); assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); @@ -314,7 +321,7 @@ void test8() // Test 8.1 split_stripes(2, 128*1024, 0, 128*1024+4096, stripes); void *write_buf = malloc(128*1024+4096); - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 2, write_osd_set, 128*1024, 0); assert(stripes[0].read_start == 0 && stripes[0].read_end == 0); assert(stripes[1].read_start == 4096 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 0 && stripes[2].read_end == 0); @@ -330,7 +337,7 @@ void test8() // Test 8.2 set_pattern(write_buf, 128*1024+4096, PATTERN0); set_pattern(stripes[1].read_buf, 128*1024-4096, PATTERN1); - calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 0 && stripes[0].write_end == 128*1024); // recheck again assert(stripes[1].write_start == 0 && stripes[1].write_end == 4096); // recheck again assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); // recheck again @@ -373,7 +380,7 @@ void test9() assert(stripes[2].req_start == 0 && stripes[2].req_end == 0); // Test 9.1 void *write_buf = NULL; - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024, 0); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 0 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 0 && stripes[2].read_end == 128*1024); @@ -389,7 +396,7 @@ void test9() // Test 9.2 set_pattern(stripes[1].read_buf, 128*1024, 0); set_pattern(stripes[2].read_buf, 128*1024, PATTERN1); - calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 0 && stripes[0].write_end == 128*1024); assert(stripes[1].write_start == 0 && stripes[1].write_end == 0); assert(stripes[2].write_start == 0 && stripes[2].write_end == 0); @@ -428,7 +435,7 @@ void test10() assert(stripes[2].req_start == 0 && stripes[2].req_end == 0); // Test 10.1 void *write_buf = malloc(256*1024); - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024, 0); assert(rmw_buf); assert(stripes[0].read_start == 0 && stripes[0].read_end == 0); assert(stripes[1].read_start == 0 && stripes[1].read_end == 0); @@ -445,7 +452,7 @@ void test10() // Test 10.2 set_pattern(stripes[0].write_buf, 128*1024, PATTERN1); set_pattern(stripes[1].write_buf, 128*1024, PATTERN2); - calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 0 && stripes[0].write_end == 128*1024); assert(stripes[1].write_start == 0 && stripes[1].write_end == 128*1024); assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); @@ -484,7 +491,7 @@ void test11() assert(stripes[2].req_start == 0 && stripes[2].req_end == 0); // Test 11.1 void *write_buf = malloc(256*1024); - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024, 0); assert(rmw_buf); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 0 && stripes[1].read_end == 0); @@ -501,7 +508,7 @@ void test11() // Test 11.2 set_pattern(stripes[0].read_buf, 128*1024, PATTERN1); set_pattern(stripes[1].write_buf, 128*1024, PATTERN2); - calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 0 && stripes[0].write_end == 0); assert(stripes[1].write_start == 0 && stripes[1].write_end == 128*1024); assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); @@ -539,7 +546,7 @@ void test12() assert(stripes[1].req_start == 0 && stripes[1].req_end == 0); assert(stripes[2].req_start == 0 && stripes[2].req_end == 0); // Test 12.1 - void *rmw_buf = calc_rmw(NULL, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(NULL, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024, 0); assert(rmw_buf); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 0 && stripes[1].read_end == 128*1024); @@ -556,7 +563,7 @@ void test12() // Test 12.2 set_pattern(stripes[0].read_buf, 128*1024, PATTERN1); set_pattern(stripes[1].read_buf, 128*1024, PATTERN2); - calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_xor(stripes, 3, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 0 && stripes[0].write_end == 0); assert(stripes[1].write_start == 0 && stripes[1].write_end == 0); assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); @@ -596,7 +603,7 @@ void test13() assert(stripes[2].req_start == 0 && stripes[2].req_end == 0); assert(stripes[3].req_start == 0 && stripes[3].req_end == 0); // Test 13.1 - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 4, 2, 4, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 4, 2, 4, write_osd_set, 128*1024, 0); assert(rmw_buf); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024-4096); assert(stripes[1].read_start == 4096 && stripes[1].read_end == 128*1024); @@ -618,7 +625,7 @@ void test13() set_pattern(write_buf, 8192, PATTERN3); set_pattern(stripes[0].read_buf, 128*1024-4096, PATTERN1); set_pattern(stripes[1].read_buf, 128*1024-4096, PATTERN2); - calc_rmw_parity_jerasure(stripes, 4, 2, osd_set, write_osd_set, 128*1024); + calc_rmw_parity_jerasure(stripes, 4, 2, osd_set, write_osd_set, 128*1024, 0); assert(stripes[0].write_start == 128*1024-4096 && stripes[0].write_end == 128*1024); assert(stripes[1].write_start == 0 && stripes[1].write_end == 4096); assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); @@ -645,7 +652,7 @@ void test13() assert(stripes[1].read_start == 0 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 0 && stripes[2].read_end == 128*1024); assert(stripes[3].read_start == 0 && stripes[3].read_end == 128*1024); - void *read_buf = alloc_read_buffer(stripes, 4, 0); + void *read_buf = alloc_read_buffer(stripes, 4, 0, 0); assert(read_buf); assert(stripes[0].read_buf == read_buf); assert(stripes[1].read_buf == read_buf+128*1024); @@ -653,7 +660,7 @@ void test13() assert(stripes[3].read_buf == read_buf+3*128*1024); memcpy(read_buf+2*128*1024, rmw_buf, 128*1024); memcpy(read_buf+3*128*1024, rmw_buf+128*1024, 128*1024); - reconstruct_stripes_jerasure(stripes, 4, 2); + reconstruct_stripes_jerasure(stripes, 4, 2, 0); check_pattern(stripes[0].read_buf, 128*1024-4096, PATTERN1); check_pattern(stripes[0].read_buf+128*1024-4096, 4096, PATTERN3); check_pattern(stripes[1].read_buf, 4096, PATTERN3); @@ -676,7 +683,7 @@ void test13() assert(stripes[1].read_start == 0 && stripes[1].read_end == 0); assert(stripes[2].read_start == 0 && stripes[2].read_end == 128*1024); assert(stripes[3].read_start == 0 && stripes[3].read_end == 128*1024); - read_buf = alloc_read_buffer(stripes, 4, 0); + read_buf = alloc_read_buffer(stripes, 4, 0, 0); assert(read_buf); assert(stripes[0].read_buf == read_buf); assert(stripes[1].read_buf == NULL); @@ -684,7 +691,7 @@ void test13() assert(stripes[3].read_buf == read_buf+2*128*1024); memcpy(read_buf+128*1024, rmw_buf, 128*1024); memcpy(read_buf+2*128*1024, rmw_buf+128*1024, 128*1024); - reconstruct_stripes_jerasure(stripes, 4, 2); + reconstruct_stripes_jerasure(stripes, 4, 2, 0); check_pattern(stripes[0].read_buf, 128*1024-4096, PATTERN1); check_pattern(stripes[0].read_buf+128*1024-4096, 4096, PATTERN3); free(read_buf); @@ -711,6 +718,7 @@ void test13() void test14() { + const int bmp = 4; use_jerasure(3, 2, true); osd_num_t osd_set[3] = { 1, 2, 0 }; osd_num_t write_osd_set[3] = { 1, 2, 3 }; @@ -722,7 +730,7 @@ void test14() assert(stripes[1].req_start == 0 && stripes[1].req_end == 4096); assert(stripes[2].req_start == 0 && stripes[2].req_end == 0); // Test 13.1 - void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024); + void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 3, 2, 3, write_osd_set, 128*1024, bmp); assert(rmw_buf); assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024-4096); assert(stripes[1].read_start == 4096 && stripes[1].read_end == 128*1024); @@ -740,7 +748,13 @@ void test14() set_pattern(write_buf, 8192, PATTERN3); set_pattern(stripes[0].read_buf, 128*1024-4096, PATTERN1); set_pattern(stripes[1].read_buf, 128*1024-4096, PATTERN2); - calc_rmw_parity_jerasure(stripes, 3, 2, osd_set, write_osd_set, 128*1024); + memset(stripes[0].bmp_buf, 0, bmp); + memset(stripes[1].bmp_buf, 0, bmp); + memset(stripes[2].bmp_buf, 0, bmp); + calc_rmw_parity_jerasure(stripes, 3, 2, osd_set, write_osd_set, 128*1024, bmp); + assert(*(uint32_t*)stripes[0].bmp_buf == 0x80000000); + assert(*(uint32_t*)stripes[1].bmp_buf == 0x00000001); + assert(*(uint32_t*)stripes[2].bmp_buf == 0x80000001); // jerasure 2+1 is still just XOR assert(stripes[0].write_start == 128*1024-4096 && stripes[0].write_end == 128*1024); assert(stripes[1].write_start == 0 && stripes[1].write_end == 4096); assert(stripes[2].write_start == 0 && stripes[2].write_end == 128*1024); @@ -763,7 +777,7 @@ void test14() assert(stripes[0].read_start == 0 && stripes[0].read_end == 128*1024); assert(stripes[1].read_start == 0 && stripes[1].read_end == 128*1024); assert(stripes[2].read_start == 0 && stripes[2].read_end == 128*1024); - void *read_buf = alloc_read_buffer(stripes, 3, 0); + void *read_buf = alloc_read_buffer(stripes, 3, 0, bmp); assert(read_buf); assert(stripes[0].read_buf == read_buf); assert(stripes[1].read_buf == read_buf+128*1024); @@ -771,7 +785,7 @@ void test14() set_pattern(stripes[1].read_buf, 4096, PATTERN3); set_pattern(stripes[1].read_buf+4096, 128*1024-4096, PATTERN2); memcpy(stripes[2].read_buf, rmw_buf, 128*1024); - reconstruct_stripes_jerasure(stripes, 3, 2); + reconstruct_stripes_jerasure(stripes, 3, 2, bmp); check_pattern(stripes[0].read_buf, 128*1024-4096, PATTERN1); check_pattern(stripes[0].read_buf+128*1024-4096, 4096, PATTERN3); free(read_buf);