diff options
Diffstat (limited to 'fs/exofs/ore.c')
-rw-r--r-- | fs/exofs/ore.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index fd6090ddd3bf..08ee454b2187 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c | |||
@@ -95,6 +95,14 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout) | |||
95 | layout->max_io_length = | 95 | layout->max_io_length = |
96 | (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * | 96 | (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * |
97 | layout->group_width; | 97 | layout->group_width; |
98 | if (layout->parity) { | ||
99 | unsigned stripe_length = | ||
100 | (layout->group_width - layout->parity) * | ||
101 | layout->stripe_unit; | ||
102 | |||
103 | layout->max_io_length /= stripe_length; | ||
104 | layout->max_io_length *= stripe_length; | ||
105 | } | ||
98 | return 0; | 106 | return 0; |
99 | } | 107 | } |
100 | EXPORT_SYMBOL(ore_verify_layout); | 108 | EXPORT_SYMBOL(ore_verify_layout); |
@@ -118,7 +126,7 @@ static struct osd_dev *_ios_od(struct ore_io_state *ios, unsigned index) | |||
118 | return ore_comp_dev(ios->oc, index); | 126 | return ore_comp_dev(ios->oc, index); |
119 | } | 127 | } |
120 | 128 | ||
121 | static int _ore_get_io_state(struct ore_layout *layout, | 129 | int _ore_get_io_state(struct ore_layout *layout, |
122 | struct ore_components *oc, unsigned numdevs, | 130 | struct ore_components *oc, unsigned numdevs, |
123 | unsigned sgs_per_dev, unsigned num_par_pages, | 131 | unsigned sgs_per_dev, unsigned num_par_pages, |
124 | struct ore_io_state **pios) | 132 | struct ore_io_state **pios) |
@@ -334,7 +342,7 @@ static void _done_io(struct osd_request *or, void *p) | |||
334 | kref_put(&ios->kref, _last_io); | 342 | kref_put(&ios->kref, _last_io); |
335 | } | 343 | } |
336 | 344 | ||
337 | static int ore_io_execute(struct ore_io_state *ios) | 345 | int ore_io_execute(struct ore_io_state *ios) |
338 | { | 346 | { |
339 | DECLARE_COMPLETION_ONSTACK(wait); | 347 | DECLARE_COMPLETION_ONSTACK(wait); |
340 | bool sync = (ios->done == NULL); | 348 | bool sync = (ios->done == NULL); |
@@ -597,6 +605,8 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, | |||
597 | ret = -ENOMEM; | 605 | ret = -ENOMEM; |
598 | goto out; | 606 | goto out; |
599 | } | 607 | } |
608 | _add_stripe_page(ios->sp2d, &ios->si, pages[pg]); | ||
609 | |||
600 | pgbase = 0; | 610 | pgbase = 0; |
601 | ++pg; | 611 | ++pg; |
602 | } | 612 | } |
@@ -636,6 +646,7 @@ static int _prepare_for_striping(struct ore_io_state *ios) | |||
636 | 646 | ||
637 | dev_order = _dev_order(devs_in_group, mirrors_p1, si->par_dev, dev); | 647 | dev_order = _dev_order(devs_in_group, mirrors_p1, si->par_dev, dev); |
638 | si->cur_comp = dev_order; | 648 | si->cur_comp = dev_order; |
649 | si->cur_pg = si->unit_off / PAGE_SIZE; | ||
639 | 650 | ||
640 | while (length) { | 651 | while (length) { |
641 | unsigned comp = dev - first_dev; | 652 | unsigned comp = dev - first_dev; |
@@ -677,14 +688,14 @@ static int _prepare_for_striping(struct ore_io_state *ios) | |||
677 | length -= cur_len; | 688 | length -= cur_len; |
678 | 689 | ||
679 | si->cur_comp = (si->cur_comp + 1) % group_width; | 690 | si->cur_comp = (si->cur_comp + 1) % group_width; |
680 | if (unlikely((dev == si->par_dev) || | 691 | if (unlikely((dev == si->par_dev) || (!length && ios->sp2d))) { |
681 | (!length && ios->parity_pages))) { | 692 | if (!length && ios->sp2d) { |
682 | if (!length) | ||
683 | /* If we are writing and this is the very last | 693 | /* If we are writing and this is the very last |
684 | * stripe. then operate on parity dev. | 694 | * stripe. then operate on parity dev. |
685 | */ | 695 | */ |
686 | dev = si->par_dev; | 696 | dev = si->par_dev; |
687 | if (ios->reading) | 697 | } |
698 | if (ios->sp2d) | ||
688 | /* In writes cur_len just means if it's the | 699 | /* In writes cur_len just means if it's the |
689 | * last one. See _ore_add_parity_unit. | 700 | * last one. See _ore_add_parity_unit. |
690 | */ | 701 | */ |
@@ -709,6 +720,7 @@ static int _prepare_for_striping(struct ore_io_state *ios) | |||
709 | devs_in_group + first_dev; | 720 | devs_in_group + first_dev; |
710 | /* Next stripe, start fresh */ | 721 | /* Next stripe, start fresh */ |
711 | si->cur_comp = 0; | 722 | si->cur_comp = 0; |
723 | si->cur_pg = 0; | ||
712 | } | 724 | } |
713 | } | 725 | } |
714 | out: | 726 | out: |
@@ -873,6 +885,14 @@ int ore_write(struct ore_io_state *ios) | |||
873 | int i; | 885 | int i; |
874 | int ret; | 886 | int ret; |
875 | 887 | ||
888 | if (unlikely(ios->sp2d && !ios->r4w)) { | ||
889 | /* A library is attempting a RAID-write without providing | ||
890 | * a pages lock interface. | ||
891 | */ | ||
892 | WARN_ON_ONCE(1); | ||
893 | return -ENOTSUPP; | ||
894 | } | ||
895 | |||
876 | ret = _prepare_for_striping(ios); | 896 | ret = _prepare_for_striping(ios); |
877 | if (unlikely(ret)) | 897 | if (unlikely(ret)) |
878 | return ret; | 898 | return ret; |
@@ -888,7 +908,7 @@ int ore_write(struct ore_io_state *ios) | |||
888 | } | 908 | } |
889 | EXPORT_SYMBOL(ore_write); | 909 | EXPORT_SYMBOL(ore_write); |
890 | 910 | ||
891 | static int _read_mirror(struct ore_io_state *ios, unsigned cur_comp) | 911 | int _ore_read_mirror(struct ore_io_state *ios, unsigned cur_comp) |
892 | { | 912 | { |
893 | struct osd_request *or; | 913 | struct osd_request *or; |
894 | struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp]; | 914 | struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp]; |
@@ -952,7 +972,7 @@ int ore_read(struct ore_io_state *ios) | |||
952 | return ret; | 972 | return ret; |
953 | 973 | ||
954 | for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { | 974 | for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { |
955 | ret = _read_mirror(ios, i); | 975 | ret = _ore_read_mirror(ios, i); |
956 | if (unlikely(ret)) | 976 | if (unlikely(ret)) |
957 | return ret; | 977 | return ret; |
958 | } | 978 | } |