/* * Select data reconstruction method for raidz_map * @parity_valid - Parity validity flag * @dt - Failed data index array * @nbaddata - Number of failed data columns */ int vdev_raidz_math_reconstruct(raidz_map_t *rm, const int *parity_valid, const int *dt, const int nbaddata) { raidz_rec_f rec_fn = NULL; switch (raidz_parity(rm)) { case PARITY_P: rec_fn = reconstruct_fun_p_sel(rm, parity_valid, nbaddata); break; case PARITY_PQ: rec_fn = reconstruct_fun_pq_sel(rm, parity_valid, nbaddata); break; case PARITY_PQR: rec_fn = reconstruct_fun_pqr_sel(rm, parity_valid, nbaddata); break; default: cmn_err(CE_PANIC, "invalid RAID-Z configuration %d", raidz_parity(rm)); break; } if (rec_fn == NULL) return (RAIDZ_ORIGINAL_IMPL); else return (rec_fn(rm, dt)); }
/* * Select parity generation method for raidz_map */ int vdev_raidz_math_generate(raidz_map_t *rm) { raidz_gen_f gen_parity = NULL; switch (raidz_parity(rm)) { case 1: gen_parity = rm->rm_ops->gen[RAIDZ_GEN_P]; break; case 2: gen_parity = rm->rm_ops->gen[RAIDZ_GEN_PQ]; break; case 3: gen_parity = rm->rm_ops->gen[RAIDZ_GEN_PQR]; break; default: gen_parity = NULL; cmn_err(CE_PANIC, "invalid RAID-Z configuration %d", raidz_parity(rm)); break; } /* if method is NULL execute the original implementation */ if (gen_parity == NULL) return (RAIDZ_ORIGINAL_IMPL); gen_parity(rm); return (0); }
/* * Select data reconstruction method for raidz_map * @parity_valid - Parity validity flag * @dt - Failed data index array * @nbaddata - Number of failed data columns */ int vdev_raidz_math_reconstruct(raidz_map_t *rm, const int *parity_valid, const int *dt, const int nbaddata) { raidz_rec_f rec_data = NULL; switch (raidz_parity(rm)) { case 1: rec_data = _reconstruct_fun_raidz1(rm, parity_valid, nbaddata); break; case 2: rec_data = _reconstruct_fun_raidz2(rm, parity_valid, nbaddata); break; case 3: rec_data = _reconstruct_fun_raidz3(rm, parity_valid, nbaddata); break; default: cmn_err(CE_PANIC, "invalid RAID-Z configuration %d", raidz_parity(rm)); break; } ASSERT(rec_data != NULL); return (rec_data(rm, dt)); }
/* * Select parity generation method for raidz_map */ void vdev_raidz_math_generate(raidz_map_t *rm) { raidz_gen_f gen_parity = NULL; switch (raidz_parity(rm)) { case 1: gen_parity = rm->rm_ops->gen[RAIDZ_GEN_P]; break; case 2: gen_parity = rm->rm_ops->gen[RAIDZ_GEN_PQ]; break; case 3: gen_parity = rm->rm_ops->gen[RAIDZ_GEN_PQR]; break; default: gen_parity = NULL; cmn_err(CE_PANIC, "invalid RAID-Z configuration %d", raidz_parity(rm)); break; } ASSERT(gen_parity != NULL); gen_parity(rm); }
static void run_rec_bench_impl(const char *impl) { int fn, ncols, nbad; uint64_t ds, iter_cnt, iter, disksize; hrtime_t start; double elapsed, d_bw; static const int tgt[7][3] = { {1, 2, 3}, /* rec_p: bad QR & D[0] */ {0, 2, 3}, /* rec_q: bad PR & D[0] */ {0, 1, 3}, /* rec_r: bad PQ & D[0] */ {2, 3, 4}, /* rec_pq: bad R & D[0][1] */ {1, 3, 4}, /* rec_pr: bad Q & D[0][1] */ {0, 3, 4}, /* rec_qr: bad P & D[0][1] */ {3, 4, 5} /* rec_pqr: bad & D[0][1][2] */ }; for (fn = 0; fn < RAIDZ_REC_NUM; fn++) { for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) { /* create suitable raidz_map */ ncols = rto_opts.rto_dcols + PARITY_PQR; zio_bench.io_size = 1ULL << ds; /* * raidz block is too short to test * the requested method */ if (zio_bench.io_size / rto_opts.rto_dcols < (1ULL << BENCH_ASHIFT)) continue; rm_bench = vdev_raidz_map_alloc(&zio_bench, BENCH_ASHIFT, ncols, PARITY_PQR); /* estimate iteration count */ iter_cnt = (REC_BENCH_MEMORY); iter_cnt /= zio_bench.io_size; /* calculate how many bad columns there are */ nbad = MIN(3, raidz_ncols(rm_bench) - raidz_parity(rm_bench)); start = gethrtime(); for (iter = 0; iter < iter_cnt; iter++) vdev_raidz_reconstruct(rm_bench, tgt[fn], nbad); elapsed = NSEC2SEC((double) (gethrtime() - start)); disksize = (1ULL << ds) / rto_opts.rto_dcols; d_bw = (double)iter_cnt * (double)(disksize); d_bw /= (1024.0 * 1024.0 * elapsed); LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n", impl, raidz_rec_name[fn], rto_opts.rto_dcols, (1ULL<<ds), d_bw, d_bw * (double)ncols, (unsigned) iter_cnt); vdev_raidz_map_free(rm_bench); } } }