diff options
Diffstat (limited to 'fs/exofs/ore_raid.c')
-rw-r--r-- | fs/exofs/ore_raid.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c index d58a952e28bc..7f20f25c232c 100644 --- a/fs/exofs/ore_raid.c +++ b/fs/exofs/ore_raid.c | |||
@@ -218,20 +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, | ||
229 | NULL, NULL, NULL, (addr_conv_t *)_1ps->scribble); | 233 | NULL, NULL, NULL, (addr_conv_t *)_1ps->scribble); |
230 | 234 | ||
231 | /* TODO: raid6 */ | 235 | if (sp2d->parity == 1) |
232 | _1ps->tx = async_xor(_1ps->pages[sp2d->data_devs], _1ps->pages, | 236 | _1ps->tx = async_xor(_1ps->pages[sp2d->data_devs], |
233 | 0, sp2d->data_devs, PAGE_SIZE, | 237 | _1ps->pages, 0, sp2d->data_devs, |
234 | &_1ps->submit); | 238 | PAGE_SIZE, &_1ps->submit); |
239 | else /* parity == 2 */ | ||
240 | _1ps->tx = async_gen_syndrome(_1ps->pages, 0, | ||
241 | sp2d->data_devs + sp2d->parity, | ||
242 | PAGE_SIZE, &_1ps->submit); | ||
235 | } | 243 | } |
236 | 244 | ||
237 | for (p = 0; p < sp2d->pages_in_unit; p++) { | 245 | for (p = 0; p < sp2d->pages_in_unit; p++) { |
@@ -616,7 +624,7 @@ static int _read_4_write_execute(struct ore_io_state *ios) | |||
616 | int _ore_add_parity_unit(struct ore_io_state *ios, | 624 | int _ore_add_parity_unit(struct ore_io_state *ios, |
617 | struct ore_striping_info *si, | 625 | struct ore_striping_info *si, |
618 | struct ore_per_dev_state *per_dev, | 626 | struct ore_per_dev_state *per_dev, |
619 | unsigned cur_len) | 627 | unsigned cur_len, bool do_xor) |
620 | { | 628 | { |
621 | if (ios->reading) { | 629 | if (ios->reading) { |
622 | if (per_dev->cur_sg >= ios->sgs_per_dev) { | 630 | if (per_dev->cur_sg >= ios->sgs_per_dev) { |
@@ -641,9 +649,11 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
641 | /* If first stripe, Read in all read4write pages | 649 | /* If first stripe, Read in all read4write pages |
642 | * (if needed) before we calculate the first parity. | 650 | * (if needed) before we calculate the first parity. |
643 | */ | 651 | */ |
644 | _read_4_write_first_stripe(ios); | 652 | if (do_xor) |
653 | _read_4_write_first_stripe(ios); | ||
645 | } | 654 | } |
646 | 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 */ | ||
647 | _read_4_write_last_stripe(ios); | 657 | _read_4_write_last_stripe(ios); |
648 | _read_4_write_execute(ios); | 658 | _read_4_write_execute(ios); |
649 | 659 | ||
@@ -655,7 +665,7 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
655 | ++(ios->cur_par_page); | 665 | ++(ios->cur_par_page); |
656 | } | 666 | } |
657 | 667 | ||
658 | BUG_ON(si->cur_comp != sp2d->data_devs); | 668 | BUG_ON(si->cur_comp < sp2d->data_devs); |
659 | BUG_ON(si->cur_pg + num_pages > sp2d->pages_in_unit); | 669 | BUG_ON(si->cur_pg + num_pages > sp2d->pages_in_unit); |
660 | 670 | ||
661 | ret = _ore_add_stripe_unit(ios, &array_start, 0, pages, | 671 | ret = _ore_add_stripe_unit(ios, &array_start, 0, pages, |
@@ -663,9 +673,10 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
663 | if (unlikely(ret)) | 673 | if (unlikely(ret)) |
664 | return ret; | 674 | return ret; |
665 | 675 | ||
666 | /* TODO: raid6 if (last_parity_dev) */ | 676 | if (do_xor) { |
667 | _gen_xor_unit(sp2d); | 677 | _gen_xor_unit(sp2d); |
668 | _sp2d_reset(sp2d, ios->r4w, ios->private); | 678 | _sp2d_reset(sp2d, ios->r4w, ios->private); |
679 | } | ||
669 | } | 680 | } |
670 | return 0; | 681 | return 0; |
671 | } | 682 | } |