aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/ore_raid.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-07 20:07:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-07 20:07:20 -0400
commit9d2cd01b15d0782adb81e40094b67904d77b03df (patch)
treef8091fcd05f463a0b31485cfe3edcef0d0211da9 /fs/exofs/ore_raid.c
parent57d326169e878a1a37b2bccd1cf81f6809ee67b9 (diff)
parentce5d36aac26cc395fe3bc45525cdbad3644f01e5 (diff)
Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd into next
Pull exofs raid6 support from Boaz Harrosh: "These simple patches will enable raid6 using the kernel's raid6_pq engine for support under exofs and pnfs-objects. There is nothing needed to do at exofs and pnfs-obj. Just fire your mkfs.exofs with --raid=6 (that was already supported before) and off you go as usual. The ORE will pick up the new map and will start writing two devices of redundancy bits. The patches are so simple because most of the ORE was already for the general raid case, only a few bug fixes were needed and the actual wiring into the raid6_pq engine" * 'for-linus' of git://git.open-osd.org/linux-open-osd: ore: Support for raid 6 ore: Remove redundant dev_order(), more cleanups ore: (trivial) reformat some code
Diffstat (limited to 'fs/exofs/ore_raid.c')
-rw-r--r--fs/exofs/ore_raid.c56
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)
218static void _gen_xor_unit(struct __stripe_pages_2d *sp2d) 218static 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)
620int _ore_add_parity_unit(struct ore_io_state *ios, 624int _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}