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.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index b74422888604..dae884694bd9 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -103,7 +103,7 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
103 103
104 layout->max_io_length = 104 layout->max_io_length =
105 (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * 105 (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) *
106 layout->group_width; 106 (layout->group_width - layout->parity);
107 if (layout->parity) { 107 if (layout->parity) {
108 unsigned stripe_length = 108 unsigned stripe_length =
109 (layout->group_width - layout->parity) * 109 (layout->group_width - layout->parity) *
@@ -286,7 +286,8 @@ int ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
286 if (length) { 286 if (length) {
287 ore_calc_stripe_info(layout, offset, length, &ios->si); 287 ore_calc_stripe_info(layout, offset, length, &ios->si);
288 ios->length = ios->si.length; 288 ios->length = ios->si.length;
289 ios->nr_pages = (ios->length + PAGE_SIZE - 1) / PAGE_SIZE; 289 ios->nr_pages = ((ios->offset & (PAGE_SIZE - 1)) +
290 ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
290 if (layout->parity) 291 if (layout->parity)
291 _ore_post_alloc_raid_stuff(ios); 292 _ore_post_alloc_raid_stuff(ios);
292 } 293 }
@@ -430,8 +431,12 @@ int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error)
430 if (likely(!ret)) 431 if (likely(!ret))
431 continue; 432 continue;
432 433
433 if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { 434 if ((OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) &&
434 /* start read offset passed endof file */ 435 per_dev->bio) {
436 /* start read offset passed endof file.
437 * Note: if we do not have bio it means read-attributes
438 * In this case we should return error to caller.
439 */
435 _clear_bio(per_dev->bio); 440 _clear_bio(per_dev->bio);
436 ORE_DBGMSG("start read offset passed end of file " 441 ORE_DBGMSG("start read offset passed end of file "
437 "offset=0x%llx, length=0x%llx\n", 442 "offset=0x%llx, length=0x%llx\n",
@@ -536,6 +541,7 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
536 u64 H = LmodS - G * T; 541 u64 H = LmodS - G * T;
537 542
538 u32 N = div_u64(H, U); 543 u32 N = div_u64(H, U);
544 u32 Nlast;
539 545
540 /* "H - (N * U)" is just "H % U" so it's bound to u32 */ 546 /* "H - (N * U)" is just "H % U" so it's bound to u32 */
541 u32 C = (u32)(H - (N * U)) / stripe_unit + G * group_width; 547 u32 C = (u32)(H - (N * U)) / stripe_unit + G * group_width;
@@ -568,6 +574,10 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
568 si->length = T - H; 574 si->length = T - H;
569 if (si->length > length) 575 if (si->length > length)
570 si->length = length; 576 si->length = length;
577
578 Nlast = div_u64(H + si->length + U - 1, U);
579 si->maxdevUnits = Nlast - N;
580
571 si->M = M; 581 si->M = M;
572} 582}
573EXPORT_SYMBOL(ore_calc_stripe_info); 583EXPORT_SYMBOL(ore_calc_stripe_info);
@@ -583,13 +593,16 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg,
583 int ret; 593 int ret;
584 594
585 if (per_dev->bio == NULL) { 595 if (per_dev->bio == NULL) {
586 unsigned pages_in_stripe = ios->layout->group_width * 596 unsigned bio_size;
587 (ios->layout->stripe_unit / PAGE_SIZE); 597
588 unsigned nr_pages = ios->nr_pages * ios->layout->group_width / 598 if (!ios->reading) {
589 (ios->layout->group_width - 599 bio_size = ios->si.maxdevUnits;
590 ios->layout->parity); 600 } else {
591 unsigned bio_size = (nr_pages + pages_in_stripe) / 601 bio_size = (ios->si.maxdevUnits + 1) *
592 ios->layout->group_width; 602 (ios->layout->group_width - ios->layout->parity) /
603 ios->layout->group_width;
604 }
605 bio_size *= (ios->layout->stripe_unit / PAGE_SIZE);
593 606
594 per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size); 607 per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
595 if (unlikely(!per_dev->bio)) { 608 if (unlikely(!per_dev->bio)) {
@@ -609,8 +622,12 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg,
609 added_len = bio_add_pc_page(q, per_dev->bio, pages[pg], 622 added_len = bio_add_pc_page(q, per_dev->bio, pages[pg],
610 pglen, pgbase); 623 pglen, pgbase);
611 if (unlikely(pglen != added_len)) { 624 if (unlikely(pglen != added_len)) {
612 ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=%u\n", 625 /* If bi_vcnt == bi_max then this is a SW BUG */
613 per_dev->bio->bi_vcnt); 626 ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=0x%x "
627 "bi_max=0x%x BIO_MAX=0x%x cur_len=0x%x\n",
628 per_dev->bio->bi_vcnt,
629 per_dev->bio->bi_max_vecs,
630 BIO_MAX_PAGES_KMALLOC, cur_len);
614 ret = -ENOMEM; 631 ret = -ENOMEM;
615 goto out; 632 goto out;
616 } 633 }
@@ -1098,7 +1115,7 @@ int ore_truncate(struct ore_layout *layout, struct ore_components *oc,
1098 size_attr->attr = g_attr_logical_length; 1115 size_attr->attr = g_attr_logical_length;
1099 size_attr->attr.val_ptr = &size_attr->newsize; 1116 size_attr->attr.val_ptr = &size_attr->newsize;
1100 1117
1101 ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", 1118 ORE_DBGMSG2("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
1102 _LLU(oc->comps->obj.id), _LLU(obj_size), i); 1119 _LLU(oc->comps->obj.id), _LLU(obj_size), i);
1103 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, 1120 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
1104 &size_attr->attr); 1121 &size_attr->attr);