25 #include <linux/slab.h>
26 #include <linux/module.h>
27 #include <asm/div64.h>
47 (
PAGE_SIZE -
sizeof(
struct bio)) / sizeof(struct bio_vec),};
63 ORE_ERR(
"Only RAID_0/5 for now\n");
68 " must be Multples of PAGE_SIZE(0x%lx)\n",
74 ORE_ERR(
"group_depth == 0 && group_width != 0\n");
79 "numdevs=%d < group_width=%d * mirrors=%d\n",
89 "group_width == 0 && group_depth == %lld\n",
98 if (stripe_length >= (1ULL << 32)) {
99 ORE_ERR(
"Stripe_length(0x%llx) >= 32bit is not supported\n",
100 _LLU(stripe_length));
108 unsigned stripe_length =
121 return ios->
oc->comps[index & ios->
oc->single_comp].cred;
126 return &ios->
oc->comps[index & ios->
oc->single_comp].obj;
131 ORE_DBGMSG2(
"oc->first_dev=%d oc->numdevs=%d i=%d oc->ods=%p\n",
132 ios->
oc->first_dev, ios->
oc->numdevs, index,
135 return ore_comp_dev(ios->
oc, index);
140 unsigned sgs_per_dev,
unsigned num_par_pages,
146 struct __alloc_all_io_state {
148 struct ore_per_dev_state per_dev[numdevs];
151 struct page *pages[num_par_pages];
163 pages = num_par_pages ? _aios->
pages :
NULL;
164 sgilist = sgs_per_dev ? _aios->sglist :
NULL;
167 struct __alloc_small_io_state {
169 struct ore_per_dev_state per_dev[numdevs];
173 struct page *pages[num_par_pages];
176 _aio_small = kzalloc(
sizeof(*_aio_small),
GFP_KERNEL);
178 ORE_DBGMSG(
"Failed alloc first part bytes=%zd\n",
179 sizeof(*_aio_small));
183 extra_part = kzalloc(
sizeof(*extra_part),
GFP_KERNEL);
185 ORE_DBGMSG(
"Failed alloc second part bytes=%zd\n",
186 sizeof(*extra_part));
192 pages = num_par_pages ? extra_part->
pages :
NULL;
193 sgilist = sgs_per_dev ? extra_part->sglist :
NULL;
197 ios = &_aio_small->ios;
208 for (d = 0; d < numdevs; ++
d) {
210 sgilist += sgs_per_dev;
246 if (layout->
parity && length) {
254 num_stripes = div_u64_rem(length, stripe_size, &remainder);
258 num_raid_units = num_stripes * layout->
parity;
269 sgs_per_dev = div_u64(num_raid_units, data_devs) + 2;
273 sizeof(
struct page *);
317 for (i = 0; i < ios->
numdevs; i++) {
318 struct ore_per_dev_state *per_dev = &ios->
per_dev[
i];
339 static void _last_io(
struct kref *
kref)
351 kref_put(&ios->
kref, _last_io);
361 ios->
done = _sync_done;
365 for (i = 0; i < ios->
numdevs; i++) {
372 ORE_DBGMSG(
"Failed to osd_finalize_request() => %d\n",
378 kref_init(&ios->
kref);
380 for (i = 0; i < ios->
numdevs; i++) {
385 kref_get(&ios->
kref);
389 kref_put(&ios->
kref, _last_io);
399 static void _clear_bio(
struct bio *bio)
404 __bio_for_each_segment(bv, bio, i, 0) {
405 unsigned this_count = bv->bv_len;
408 clear_highpage(bv->bv_page);
410 zero_user(bv->bv_page, bv->bv_offset, this_count);
417 int acumulated_lin_err = 0;
420 for (i = 0; i < ios->
numdevs; i++) {
422 struct ore_per_dev_state *per_dev = &ios->
per_dev[
i];
429 ret = osd_req_decode_sense(or, &osi);
435 _clear_bio(per_dev->bio);
436 ORE_DBGMSG(
"start read offset passed end of file "
437 "offset=0x%llx, length=0x%llx\n",
438 _LLU(per_dev->offset),
439 _LLU(per_dev->length));
446 or->
in.residual : or->
out.residual;
448 unsigned dev = per_dev->dev - ios->
oc->first_dev;
456 acumulated_lin_err =
ret;
460 return acumulated_lin_err;
524 u32 D = group_width - parity;
526 u64 T = U * group_depth;
528 u64 M = div64_u64(file_offset, S);
534 u64 LmodS = file_offset - M *
S;
535 u32 G = div64_u64(LmodS, T);
536 u64 H = LmodS - G *
T;
538 u32 N = div_u64(H, U);
541 u32 C = (
u32)(H - (N * U)) / stripe_unit + G * group_width;
543 div_u64_rem(file_offset, stripe_unit, &si->
unit_off);
546 (M * group_depth * stripe_unit);
549 u32 LCMdP =
lcm(group_width, parity) / parity;
551 u32 RxP = (N % LCMdP) * parity;
552 u32 first_dev = C - C % group_width;
554 si->
par_dev = (group_width + group_width - parity - RxP) %
555 group_width + first_dev;
556 si->
dev = (group_width + C - RxP) % group_width + first_dev;
577 struct ore_per_dev_state *per_dev,
int cur_len)
579 unsigned pg = *cur_pg;
581 osd_request_queue(_ios_od(ios, per_dev->dev));
582 unsigned len = cur_len;
585 if (per_dev->bio ==
NULL) {
586 unsigned pages_in_stripe = ios->
layout->group_width *
589 (ios->
layout->group_width -
591 unsigned bio_size = (nr_pages + pages_in_stripe) /
594 per_dev->bio = bio_kmalloc(
GFP_KERNEL, bio_size);
596 ORE_DBGMSG(
"Failed to allocate BIO size=%u\n",
603 while (cur_len > 0) {
612 ORE_DBGMSG(
"Failed bio_add_pc_page bi_vcnt=%u\n",
613 per_dev->bio->bi_vcnt);
617 _add_stripe_page(ios->
sp2d, &ios->
si, pages[pg]);
624 per_dev->length += len;
635 static int _prepare_for_striping(
struct ore_io_state *ios)
639 unsigned mirrors_p1 = ios->
layout->mirrors_p1;
640 unsigned group_width = ios->
layout->group_width;
641 unsigned devs_in_group = group_width * mirrors_p1;
643 unsigned first_dev = dev - (dev % devs_in_group);
656 dev_order = _dev_order(devs_in_group, mirrors_p1, si->
par_dev, dev);
661 unsigned comp = dev - first_dev;
662 struct ore_per_dev_state *per_dev = &ios->
per_dev[comp];
663 unsigned cur_len, page_off = 0;
665 if (!per_dev->length) {
667 if (dev == si->
dev) {
670 cur_len = stripe_unit - si->
unit_off;
686 if (cur_len >= length)
695 dev = (dev % devs_in_group) + first_dev;
701 if (!length && ios->
sp2d) {
712 per_dev = &ios->
per_dev[dev - first_dev];
713 if (!per_dev->length) {
728 ios->
layout->parity * mirrors_p1) %
729 devs_in_group + first_dev;
745 for (i = 0; i < ios->
oc->numdevs; i++) {
750 ORE_ERR(
"%s: osd_start_request failed\n", __func__);
770 for (i = 0; i < ios->
oc->numdevs; i++) {
775 ORE_ERR(
"%s: osd_start_request failed\n", __func__);
791 static int _write_mirror(
struct ore_io_state *ios,
int cur_comp)
793 struct ore_per_dev_state *master_dev = &ios->
per_dev[cur_comp];
794 unsigned dev = ios->
per_dev[cur_comp].dev;
795 unsigned last_comp = cur_comp + ios->
layout->mirrors_p1;
798 if (ios->
pages && !master_dev->length)
801 for (; cur_comp < last_comp; ++cur_comp, ++
dev) {
802 struct ore_per_dev_state *per_dev = &ios->
per_dev[cur_comp];
807 ORE_ERR(
"%s: osd_start_request failed\n", __func__);
816 if (per_dev != master_dev) {
817 bio = bio_clone_kmalloc(master_dev->bio,
821 "Failed to allocate BIO size=%u\n",
822 master_dev->bio->bi_max_vecs);
829 per_dev->offset = master_dev->offset;
830 per_dev->length = master_dev->length;
834 bio = master_dev->bio;
840 per_dev->offset, bio, per_dev->length);
842 "length=0x%llx dev=%d\n",
843 _LLU(_ios_obj(ios, cur_comp)->
id),
844 _LLU(per_dev->offset),
845 _LLU(per_dev->length), dev);
847 per_dev->offset = ios->
si.obj_offset;
848 per_dev->dev = ios->
si.dev +
dev;
853 ios->
layout->stripe_unit));
861 "length=0x%llx dev=%d\n",
862 _LLU(_ios_obj(ios, cur_comp)->
id),
863 _LLU(per_dev->offset),
867 ORE_DBGMSG2(
"obj(0x%llx) set_attributes=%d dev=%d\n",
868 _LLU(_ios_obj(ios, cur_comp)->
id),
898 ret = _prepare_for_striping(ios);
902 for (i = 0; i < ios->
numdevs; i += ios->
layout->mirrors_p1) {
903 ret = _write_mirror(ios, i);
916 struct ore_per_dev_state *per_dev = &ios->
per_dev[cur_comp];
917 struct osd_obj_id *obj = _ios_obj(ios, cur_comp);
918 unsigned first_dev = (unsigned)obj->
id;
920 if (ios->
pages && !per_dev->length)
923 first_dev = per_dev->dev + first_dev % ios->
layout->mirrors_p1;
926 ORE_ERR(
"%s: osd_start_request failed\n", __func__);
932 if (per_dev->cur_sg) {
939 per_dev->sglist, per_dev->cur_sg);
943 per_dev->bio, per_dev->length);
946 ORE_DBGMSG(
"read(0x%llx) offset=0x%llx length=0x%llx"
947 " dev=%d sg_len=%d\n",
_LLU(obj->
id),
948 _LLU(per_dev->offset),
_LLU(per_dev->length),
949 first_dev, per_dev->cur_sg);
954 ORE_DBGMSG2(
"obj(0x%llx) get_attributes=%d dev=%d\n",
972 ret = _prepare_for_striping(ios);
976 for (i = 0; i < ios->
numdevs; i += ios->
layout->mirrors_p1) {
996 &cur_attr, &nelem, &iter);
1009 static int _truncate_mirrors(
struct ore_io_state *ios,
unsigned cur_comp,
1012 int last_comp = cur_comp + ios->
layout->mirrors_p1;
1014 for (; cur_comp < last_comp; ++cur_comp) {
1015 struct ore_per_dev_state *per_dev = &ios->
per_dev[cur_comp];
1020 ORE_ERR(
"%s: osd_start_request failed\n", __func__);
1059 struct exofs_trunc_attr {
1070 _calc_trunk_info(ios->
layout, size, &ti);
1072 size_attrs = kcalloc(ios->
oc->numdevs,
sizeof(*size_attrs),
1081 for (i = 0; i < ios->
numdevs; ++
i) {
1082 struct exofs_trunc_attr *size_attr = &size_attrs[
i];
1089 else if (i < ti.
si.dev)
1090 obj_size = ti.
si.obj_offset +
1091 ios->
layout->stripe_unit - ti.
si.unit_off;
1092 else if (i == ti.
si.dev)
1093 obj_size = ti.
si.obj_offset;
1095 obj_size = ti.
si.obj_offset - ti.
si.unit_off;
1099 size_attr->attr.val_ptr = &size_attr->newsize;
1101 ORE_DBGMSG(
"trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
1103 ret = _truncate_mirrors(ios, i * ios->
layout->mirrors_p1,