diff options
| -rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index f50d3e8d6f22..ea6d111b03e9 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
| @@ -570,17 +570,66 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, | |||
| 570 | return false; | 570 | return false; |
| 571 | 571 | ||
| 572 | return pgio->pg_count + req->wb_bytes <= | 572 | return pgio->pg_count + req->wb_bytes <= |
| 573 | OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; | 573 | (unsigned long)pgio->pg_layout_private; |
| 574 | } | ||
| 575 | |||
| 576 | void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) | ||
| 577 | { | ||
| 578 | pnfs_generic_pg_init_read(pgio, req); | ||
| 579 | if (unlikely(pgio->pg_lseg == NULL)) | ||
| 580 | return; /* Not pNFS */ | ||
| 581 | |||
| 582 | pgio->pg_layout_private = (void *) | ||
| 583 | OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; | ||
| 584 | } | ||
| 585 | |||
| 586 | static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout, | ||
| 587 | unsigned long *stripe_end) | ||
| 588 | { | ||
| 589 | u32 stripe_off; | ||
| 590 | unsigned stripe_size; | ||
| 591 | |||
| 592 | if (layout->raid_algorithm == PNFS_OSD_RAID_0) | ||
| 593 | return true; | ||
| 594 | |||
| 595 | stripe_size = layout->stripe_unit * | ||
| 596 | (layout->group_width - layout->parity); | ||
| 597 | |||
| 598 | div_u64_rem(offset, stripe_size, &stripe_off); | ||
| 599 | if (!stripe_off) | ||
| 600 | return true; | ||
| 601 | |||
| 602 | *stripe_end = stripe_size - stripe_off; | ||
| 603 | return false; | ||
| 604 | } | ||
| 605 | |||
| 606 | void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) | ||
| 607 | { | ||
| 608 | unsigned long stripe_end = 0; | ||
| 609 | |||
| 610 | pnfs_generic_pg_init_write(pgio, req); | ||
| 611 | if (unlikely(pgio->pg_lseg == NULL)) | ||
| 612 | return; /* Not pNFS */ | ||
| 613 | |||
| 614 | if (req->wb_offset || | ||
| 615 | !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE, | ||
| 616 | &OBJIO_LSEG(pgio->pg_lseg)->layout, | ||
| 617 | &stripe_end)) { | ||
| 618 | pgio->pg_layout_private = (void *)stripe_end; | ||
| 619 | } else { | ||
| 620 | pgio->pg_layout_private = (void *) | ||
| 621 | OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; | ||
| 622 | } | ||
| 574 | } | 623 | } |
| 575 | 624 | ||
| 576 | static const struct nfs_pageio_ops objio_pg_read_ops = { | 625 | static const struct nfs_pageio_ops objio_pg_read_ops = { |
| 577 | .pg_init = pnfs_generic_pg_init_read, | 626 | .pg_init = objio_init_read, |
| 578 | .pg_test = objio_pg_test, | 627 | .pg_test = objio_pg_test, |
| 579 | .pg_doio = pnfs_generic_pg_readpages, | 628 | .pg_doio = pnfs_generic_pg_readpages, |
| 580 | }; | 629 | }; |
| 581 | 630 | ||
| 582 | static const struct nfs_pageio_ops objio_pg_write_ops = { | 631 | static const struct nfs_pageio_ops objio_pg_write_ops = { |
| 583 | .pg_init = pnfs_generic_pg_init_write, | 632 | .pg_init = objio_init_write, |
| 584 | .pg_test = objio_pg_test, | 633 | .pg_test = objio_pg_test, |
| 585 | .pg_doio = pnfs_generic_pg_writepages, | 634 | .pg_doio = pnfs_generic_pg_writepages, |
| 586 | }; | 635 | }; |
