aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/ore.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exofs/ore.c')
-rw-r--r--fs/exofs/ore.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 0e2a8353f7cc..cfc0205d62c4 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -58,9 +58,12 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
58 layout->parity = 1; 58 layout->parity = 1;
59 break; 59 break;
60 case PNFS_OSD_RAID_PQ: 60 case PNFS_OSD_RAID_PQ:
61 layout->parity = 2;
62 break;
61 case PNFS_OSD_RAID_4: 63 case PNFS_OSD_RAID_4:
62 default: 64 default:
63 ORE_ERR("Only RAID_0/5 for now\n"); 65 ORE_ERR("Only RAID_0/5/6 for now received-enum=%d\n",
66 layout->raid_algorithm);
64 return -EINVAL; 67 return -EINVAL;
65 } 68 }
66 if (0 != (layout->stripe_unit & ~PAGE_MASK)) { 69 if (0 != (layout->stripe_unit & ~PAGE_MASK)) {
@@ -112,6 +115,8 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
112 layout->max_io_length /= stripe_length; 115 layout->max_io_length /= stripe_length;
113 layout->max_io_length *= stripe_length; 116 layout->max_io_length *= stripe_length;
114 } 117 }
118 ORE_DBGMSG("max_io_length=0x%lx\n", layout->max_io_length);
119
115 return 0; 120 return 0;
116} 121}
117EXPORT_SYMBOL(ore_verify_layout); 122EXPORT_SYMBOL(ore_verify_layout);
@@ -561,7 +566,8 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
561 566
562 si->par_dev = (group_width + group_width - parity - RxP) % 567 si->par_dev = (group_width + group_width - parity - RxP) %
563 group_width + first_dev; 568 group_width + first_dev;
564 si->dev = (group_width + C - RxP) % group_width + first_dev; 569 si->dev = (group_width + group_width + C - RxP) %
570 group_width + first_dev;
565 si->bytes_in_stripe = U; 571 si->bytes_in_stripe = U;
566 si->first_stripe_start = M * S + G * T + N * U; 572 si->first_stripe_start = M * S + G * T + N * U;
567 } else { 573 } else {
@@ -651,6 +657,43 @@ out: /* we fail the complete unit on an error eg don't advance
651 return ret; 657 return ret;
652} 658}
653 659
660static int _add_parity_units(struct ore_io_state *ios,
661 struct ore_striping_info *si,
662 unsigned dev, unsigned first_dev,
663 unsigned mirrors_p1, unsigned devs_in_group,
664 unsigned cur_len)
665{
666 unsigned do_parity;
667 int ret = 0;
668
669 for (do_parity = ios->layout->parity; do_parity; --do_parity) {
670 struct ore_per_dev_state *per_dev;
671
672 per_dev = &ios->per_dev[dev - first_dev];
673 if (!per_dev->length && !per_dev->offset) {
674 /* Only/always the parity unit of the first
675 * stripe will be empty. So this is a chance to
676 * initialize the per_dev info.
677 */
678 per_dev->dev = dev;
679 per_dev->offset = si->obj_offset - si->unit_off;
680 }
681
682 ret = _ore_add_parity_unit(ios, si, per_dev, cur_len,
683 do_parity == 1);
684 if (unlikely(ret))
685 break;
686
687 if (do_parity != 1) {
688 dev = ((dev + mirrors_p1) % devs_in_group) + first_dev;
689 si->cur_comp = (si->cur_comp + 1) %
690 ios->layout->group_width;
691 }
692 }
693
694 return ret;
695}
696
654static int _prepare_for_striping(struct ore_io_state *ios) 697static int _prepare_for_striping(struct ore_io_state *ios)
655{ 698{
656 struct ore_striping_info *si = &ios->si; 699 struct ore_striping_info *si = &ios->si;
@@ -660,7 +703,6 @@ static int _prepare_for_striping(struct ore_io_state *ios)
660 unsigned devs_in_group = group_width * mirrors_p1; 703 unsigned devs_in_group = group_width * mirrors_p1;
661 unsigned dev = si->dev; 704 unsigned dev = si->dev;
662 unsigned first_dev = dev - (dev % devs_in_group); 705 unsigned first_dev = dev - (dev % devs_in_group);
663 unsigned dev_order;
664 unsigned cur_pg = ios->pages_consumed; 706 unsigned cur_pg = ios->pages_consumed;
665 u64 length = ios->length; 707 u64 length = ios->length;
666 int ret = 0; 708 int ret = 0;
@@ -672,14 +714,13 @@ static int _prepare_for_striping(struct ore_io_state *ios)
672 714
673 BUG_ON(length > si->length); 715 BUG_ON(length > si->length);
674 716
675 dev_order = si->cur_comp;
676
677 while (length) { 717 while (length) {
678 struct ore_per_dev_state *per_dev = 718 struct ore_per_dev_state *per_dev =
679 &ios->per_dev[dev - first_dev]; 719 &ios->per_dev[dev - first_dev];
680 unsigned cur_len, page_off = 0; 720 unsigned cur_len, page_off = 0;
681 721
682 if (!per_dev->length) { 722 if (!per_dev->length && !per_dev->offset) {
723 /* First time initialize the per_dev info. */
683 per_dev->dev = dev; 724 per_dev->dev = dev;
684 if (dev == si->dev) { 725 if (dev == si->dev) {
685 WARN_ON(dev == si->par_dev); 726 WARN_ON(dev == si->par_dev);
@@ -688,13 +729,7 @@ static int _prepare_for_striping(struct ore_io_state *ios)
688 page_off = si->unit_off & ~PAGE_MASK; 729 page_off = si->unit_off & ~PAGE_MASK;
689 BUG_ON(page_off && (page_off != ios->pgbase)); 730 BUG_ON(page_off && (page_off != ios->pgbase));
690 } else { 731 } else {
691 if (si->cur_comp > dev_order) 732 per_dev->offset = si->obj_offset - si->unit_off;
692 per_dev->offset =
693 si->obj_offset - si->unit_off;
694 else /* si->cur_comp < dev_order */
695 per_dev->offset =
696 si->obj_offset + stripe_unit -
697 si->unit_off;
698 cur_len = stripe_unit; 733 cur_len = stripe_unit;
699 } 734 }
700 } else { 735 } else {
@@ -721,20 +756,12 @@ static int _prepare_for_striping(struct ore_io_state *ios)
721 /* If last stripe operate on parity comp */ 756 /* If last stripe operate on parity comp */
722 si->cur_comp = group_width - ios->layout->parity; 757 si->cur_comp = group_width - ios->layout->parity;
723 } 758 }
724 per_dev = &ios->per_dev[dev - first_dev];
725 if (!per_dev->length) {
726 /* Only/always the parity unit of the first
727 * stripe will be empty. So this is a chance to
728 * initialize the per_dev info.
729 */
730 per_dev->dev = dev;
731 per_dev->offset = si->obj_offset - si->unit_off;
732 }
733 759
734 /* In writes cur_len just means if it's the 760 /* In writes cur_len just means if it's the
735 * last one. See _ore_add_parity_unit. 761 * last one. See _ore_add_parity_unit.
736 */ 762 */
737 ret = _ore_add_parity_unit(ios, si, per_dev, 763 ret = _add_parity_units(ios, si, dev, first_dev,
764 mirrors_p1, devs_in_group,
738 ios->sp2d ? length : cur_len); 765 ios->sp2d ? length : cur_len);
739 if (unlikely(ret)) 766 if (unlikely(ret))
740 goto out; 767 goto out;
@@ -746,6 +773,8 @@ static int _prepare_for_striping(struct ore_io_state *ios)
746 /* Next stripe, start fresh */ 773 /* Next stripe, start fresh */
747 si->cur_comp = 0; 774 si->cur_comp = 0;
748 si->cur_pg = 0; 775 si->cur_pg = 0;
776 si->obj_offset += cur_len;
777 si->unit_off = 0;
749 } 778 }
750 } 779 }
751out: 780out: