diff options
Diffstat (limited to 'fs/exofs/ore_raid.c')
-rw-r--r-- | fs/exofs/ore_raid.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c index 4e2c032ab8a1..7f20f25c232c 100644 --- a/fs/exofs/ore_raid.c +++ b/fs/exofs/ore_raid.c | |||
@@ -218,22 +218,28 @@ static unsigned _sp2d_max_pg(struct __stripe_pages_2d *sp2d) | |||
218 | static void _gen_xor_unit(struct __stripe_pages_2d *sp2d) | 218 | static void _gen_xor_unit(struct __stripe_pages_2d *sp2d) |
219 | { | 219 | { |
220 | unsigned p; | 220 | unsigned p; |
221 | unsigned tx_flags = ASYNC_TX_ACK; | ||
222 | |||
223 | if (sp2d->parity == 1) | ||
224 | tx_flags |= ASYNC_TX_XOR_ZERO_DST; | ||
225 | |||
221 | for (p = 0; p < sp2d->pages_in_unit; p++) { | 226 | for (p = 0; p < sp2d->pages_in_unit; p++) { |
222 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; | 227 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; |
223 | 228 | ||
224 | if (!_1ps->write_count) | 229 | if (!_1ps->write_count) |
225 | continue; | 230 | continue; |
226 | 231 | ||
227 | init_async_submit(&_1ps->submit, | 232 | init_async_submit(&_1ps->submit, tx_flags, |
228 | ASYNC_TX_XOR_ZERO_DST | ASYNC_TX_ACK, | 233 | NULL, NULL, NULL, (addr_conv_t *)_1ps->scribble); |
229 | NULL, | 234 | |
230 | NULL, NULL, | 235 | if (sp2d->parity == 1) |
231 | (addr_conv_t *)_1ps->scribble); | 236 | _1ps->tx = async_xor(_1ps->pages[sp2d->data_devs], |
232 | 237 | _1ps->pages, 0, sp2d->data_devs, | |
233 | /* TODO: raid6 */ | 238 | PAGE_SIZE, &_1ps->submit); |
234 | _1ps->tx = async_xor(_1ps->pages[sp2d->data_devs], _1ps->pages, | 239 | else /* parity == 2 */ |
235 | 0, sp2d->data_devs, PAGE_SIZE, | 240 | _1ps->tx = async_gen_syndrome(_1ps->pages, 0, |
236 | &_1ps->submit); | 241 | sp2d->data_devs + sp2d->parity, |
242 | PAGE_SIZE, &_1ps->submit); | ||
237 | } | 243 | } |
238 | 244 | ||
239 | for (p = 0; p < sp2d->pages_in_unit; p++) { | 245 | for (p = 0; p < sp2d->pages_in_unit; p++) { |
@@ -404,9 +410,8 @@ static int _add_to_r4w_last_page(struct ore_io_state *ios, u64 *offset) | |||
404 | 410 | ||
405 | ore_calc_stripe_info(ios->layout, *offset, 0, &si); | 411 | ore_calc_stripe_info(ios->layout, *offset, 0, &si); |
406 | 412 | ||
407 | p = si.unit_off / PAGE_SIZE; | 413 | p = si.cur_pg; |
408 | c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1, | 414 | c = si.cur_comp; |
409 | ios->layout->mirrors_p1, si.par_dev, si.dev); | ||
410 | page = ios->sp2d->_1p_stripes[p].pages[c]; | 415 | page = ios->sp2d->_1p_stripes[p].pages[c]; |
411 | 416 | ||
412 | pg_len = PAGE_SIZE - (si.unit_off % PAGE_SIZE); | 417 | pg_len = PAGE_SIZE - (si.unit_off % PAGE_SIZE); |
@@ -534,9 +539,8 @@ static int _read_4_write_last_stripe(struct ore_io_state *ios) | |||
534 | goto read_it; | 539 | goto read_it; |
535 | 540 | ||
536 | ore_calc_stripe_info(ios->layout, offset, 0, &read_si); | 541 | ore_calc_stripe_info(ios->layout, offset, 0, &read_si); |
537 | p = read_si.unit_off / PAGE_SIZE; | 542 | p = read_si.cur_pg; |
538 | c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1, | 543 | c = read_si.cur_comp; |
539 | ios->layout->mirrors_p1, read_si.par_dev, read_si.dev); | ||
540 | 544 | ||
541 | if (min_p == sp2d->pages_in_unit) { | 545 | if (min_p == sp2d->pages_in_unit) { |
542 | /* Didn't do it yet */ | 546 | /* Didn't do it yet */ |
@@ -620,7 +624,7 @@ static int _read_4_write_execute(struct ore_io_state *ios) | |||
620 | int _ore_add_parity_unit(struct ore_io_state *ios, | 624 | int _ore_add_parity_unit(struct ore_io_state *ios, |
621 | struct ore_striping_info *si, | 625 | struct ore_striping_info *si, |
622 | struct ore_per_dev_state *per_dev, | 626 | struct ore_per_dev_state *per_dev, |
623 | unsigned cur_len) | 627 | unsigned cur_len, bool do_xor) |
624 | { | 628 | { |
625 | if (ios->reading) { | 629 | if (ios->reading) { |
626 | if (per_dev->cur_sg >= ios->sgs_per_dev) { | 630 | if (per_dev->cur_sg >= ios->sgs_per_dev) { |
@@ -640,17 +644,16 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
640 | si->cur_pg = _sp2d_min_pg(sp2d); | 644 | si->cur_pg = _sp2d_min_pg(sp2d); |
641 | num_pages = _sp2d_max_pg(sp2d) + 1 - si->cur_pg; | 645 | num_pages = _sp2d_max_pg(sp2d) + 1 - si->cur_pg; |
642 | 646 | ||
643 | if (!cur_len) /* If last stripe operate on parity comp */ | ||
644 | si->cur_comp = sp2d->data_devs; | ||
645 | |||
646 | if (!per_dev->length) { | 647 | if (!per_dev->length) { |
647 | per_dev->offset += si->cur_pg * PAGE_SIZE; | 648 | per_dev->offset += si->cur_pg * PAGE_SIZE; |
648 | /* If first stripe, Read in all read4write pages | 649 | /* If first stripe, Read in all read4write pages |
649 | * (if needed) before we calculate the first parity. | 650 | * (if needed) before we calculate the first parity. |
650 | */ | 651 | */ |
651 | _read_4_write_first_stripe(ios); | 652 | if (do_xor) |
653 | _read_4_write_first_stripe(ios); | ||
652 | } | 654 | } |
653 | if (!cur_len) /* If last stripe r4w pages of last stripe */ | 655 | if (!cur_len && do_xor) |
656 | /* If last stripe r4w pages of last stripe */ | ||
654 | _read_4_write_last_stripe(ios); | 657 | _read_4_write_last_stripe(ios); |
655 | _read_4_write_execute(ios); | 658 | _read_4_write_execute(ios); |
656 | 659 | ||
@@ -662,7 +665,7 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
662 | ++(ios->cur_par_page); | 665 | ++(ios->cur_par_page); |
663 | } | 666 | } |
664 | 667 | ||
665 | BUG_ON(si->cur_comp != sp2d->data_devs); | 668 | BUG_ON(si->cur_comp < sp2d->data_devs); |
666 | BUG_ON(si->cur_pg + num_pages > sp2d->pages_in_unit); | 669 | BUG_ON(si->cur_pg + num_pages > sp2d->pages_in_unit); |
667 | 670 | ||
668 | ret = _ore_add_stripe_unit(ios, &array_start, 0, pages, | 671 | ret = _ore_add_stripe_unit(ios, &array_start, 0, pages, |
@@ -670,9 +673,10 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
670 | if (unlikely(ret)) | 673 | if (unlikely(ret)) |
671 | return ret; | 674 | return ret; |
672 | 675 | ||
673 | /* TODO: raid6 if (last_parity_dev) */ | 676 | if (do_xor) { |
674 | _gen_xor_unit(sp2d); | 677 | _gen_xor_unit(sp2d); |
675 | _sp2d_reset(sp2d, ios->r4w, ios->private); | 678 | _sp2d_reset(sp2d, ios->r4w, ios->private); |
679 | } | ||
676 | } | 680 | } |
677 | return 0; | 681 | return 0; |
678 | } | 682 | } |