diff options
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/addr.c | 33 | ||||
-rw-r--r-- | fs/ceph/file.c | 2 |
2 files changed, 21 insertions, 14 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index c117c51741d5..45745aae4786 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -238,13 +238,16 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg) | |||
238 | struct inode *inode = req->r_inode; | 238 | struct inode *inode = req->r_inode; |
239 | int rc = req->r_result; | 239 | int rc = req->r_result; |
240 | int bytes = le32_to_cpu(msg->hdr.data_len); | 240 | int bytes = le32_to_cpu(msg->hdr.data_len); |
241 | int num_pages; | ||
241 | int i; | 242 | int i; |
242 | 243 | ||
243 | dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes); | 244 | dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes); |
244 | 245 | ||
245 | /* unlock all pages, zeroing any data we didn't read */ | 246 | /* unlock all pages, zeroing any data we didn't read */ |
246 | BUG_ON(req->r_data_in.type != CEPH_OSD_DATA_TYPE_PAGES); | 247 | BUG_ON(req->r_data_in.type != CEPH_OSD_DATA_TYPE_PAGES); |
247 | for (i = 0; i < req->r_data_in.num_pages; i++) { | 248 | num_pages = calc_pages_for((u64)req->r_data_in.alignment, |
249 | (u64)req->r_data_in.length); | ||
250 | for (i = 0; i < num_pages; i++) { | ||
248 | struct page *page = req->r_data_in.pages[i]; | 251 | struct page *page = req->r_data_in.pages[i]; |
249 | 252 | ||
250 | if (bytes < (int)PAGE_CACHE_SIZE) { | 253 | if (bytes < (int)PAGE_CACHE_SIZE) { |
@@ -340,7 +343,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) | |||
340 | } | 343 | } |
341 | req->r_data_in.type = CEPH_OSD_DATA_TYPE_PAGES; | 344 | req->r_data_in.type = CEPH_OSD_DATA_TYPE_PAGES; |
342 | req->r_data_in.pages = pages; | 345 | req->r_data_in.pages = pages; |
343 | req->r_data_in.num_pages = nr_pages; | 346 | req->r_data_in.length = len; |
344 | req->r_data_in.alignment = 0; | 347 | req->r_data_in.alignment = 0; |
345 | req->r_callback = finish_read; | 348 | req->r_callback = finish_read; |
346 | req->r_inode = inode; | 349 | req->r_inode = inode; |
@@ -555,6 +558,7 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
555 | struct ceph_inode_info *ci = ceph_inode(inode); | 558 | struct ceph_inode_info *ci = ceph_inode(inode); |
556 | unsigned wrote; | 559 | unsigned wrote; |
557 | struct page *page; | 560 | struct page *page; |
561 | int num_pages; | ||
558 | int i; | 562 | int i; |
559 | struct ceph_snap_context *snapc = req->r_snapc; | 563 | struct ceph_snap_context *snapc = req->r_snapc; |
560 | struct address_space *mapping = inode->i_mapping; | 564 | struct address_space *mapping = inode->i_mapping; |
@@ -565,6 +569,8 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
565 | unsigned issued = ceph_caps_issued(ci); | 569 | unsigned issued = ceph_caps_issued(ci); |
566 | 570 | ||
567 | BUG_ON(req->r_data_out.type != CEPH_OSD_DATA_TYPE_PAGES); | 571 | BUG_ON(req->r_data_out.type != CEPH_OSD_DATA_TYPE_PAGES); |
572 | num_pages = calc_pages_for((u64)req->r_data_out.alignment, | ||
573 | (u64)req->r_data_out.length); | ||
568 | if (rc >= 0) { | 574 | if (rc >= 0) { |
569 | /* | 575 | /* |
570 | * Assume we wrote the pages we originally sent. The | 576 | * Assume we wrote the pages we originally sent. The |
@@ -572,7 +578,7 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
572 | * raced with a truncation and was adjusted at the osd, | 578 | * raced with a truncation and was adjusted at the osd, |
573 | * so don't believe the reply. | 579 | * so don't believe the reply. |
574 | */ | 580 | */ |
575 | wrote = req->r_data_out.num_pages; | 581 | wrote = num_pages; |
576 | } else { | 582 | } else { |
577 | wrote = 0; | 583 | wrote = 0; |
578 | mapping_set_error(mapping, rc); | 584 | mapping_set_error(mapping, rc); |
@@ -581,7 +587,7 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
581 | inode, rc, bytes, wrote); | 587 | inode, rc, bytes, wrote); |
582 | 588 | ||
583 | /* clean all pages */ | 589 | /* clean all pages */ |
584 | for (i = 0; i < req->r_data_out.num_pages; i++) { | 590 | for (i = 0; i < num_pages; i++) { |
585 | page = req->r_data_out.pages[i]; | 591 | page = req->r_data_out.pages[i]; |
586 | BUG_ON(!page); | 592 | BUG_ON(!page); |
587 | WARN_ON(!PageUptodate(page)); | 593 | WARN_ON(!PageUptodate(page)); |
@@ -611,9 +617,9 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
611 | unlock_page(page); | 617 | unlock_page(page); |
612 | } | 618 | } |
613 | dout("%p wrote+cleaned %d pages\n", inode, wrote); | 619 | dout("%p wrote+cleaned %d pages\n", inode, wrote); |
614 | ceph_put_wrbuffer_cap_refs(ci, req->r_data_out.num_pages, snapc); | 620 | ceph_put_wrbuffer_cap_refs(ci, num_pages, snapc); |
615 | 621 | ||
616 | ceph_release_pages(req->r_data_out.pages, req->r_data_out.num_pages); | 622 | ceph_release_pages(req->r_data_out.pages, num_pages); |
617 | if (req->r_data_out.pages_from_pool) | 623 | if (req->r_data_out.pages_from_pool) |
618 | mempool_free(req->r_data_out.pages, | 624 | mempool_free(req->r_data_out.pages, |
619 | ceph_sb_to_client(inode->i_sb)->wb_pagevec_pool); | 625 | ceph_sb_to_client(inode->i_sb)->wb_pagevec_pool); |
@@ -624,15 +630,18 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
624 | 630 | ||
625 | /* | 631 | /* |
626 | * allocate a page vec, either directly, or if necessary, via a the | 632 | * allocate a page vec, either directly, or if necessary, via a the |
627 | * mempool. we avoid the mempool if we can because req->r_data_out.num_pages | 633 | * mempool. we avoid the mempool if we can because req->r_data_out.length |
628 | * may be less than the maximum write size. | 634 | * may be less than the maximum write size. |
629 | */ | 635 | */ |
630 | static void alloc_page_vec(struct ceph_fs_client *fsc, | 636 | static void alloc_page_vec(struct ceph_fs_client *fsc, |
631 | struct ceph_osd_request *req) | 637 | struct ceph_osd_request *req) |
632 | { | 638 | { |
633 | size_t size; | 639 | size_t size; |
640 | int num_pages; | ||
634 | 641 | ||
635 | size = sizeof (struct page *) * req->r_data_out.num_pages; | 642 | num_pages = calc_pages_for((u64)req->r_data_out.alignment, |
643 | (u64)req->r_data_out.length); | ||
644 | size = sizeof (struct page *) * num_pages; | ||
636 | req->r_data_out.pages = kmalloc(size, GFP_NOFS); | 645 | req->r_data_out.pages = kmalloc(size, GFP_NOFS); |
637 | if (!req->r_data_out.pages) { | 646 | if (!req->r_data_out.pages) { |
638 | req->r_data_out.pages = mempool_alloc(fsc->wb_pagevec_pool, | 647 | req->r_data_out.pages = mempool_alloc(fsc->wb_pagevec_pool, |
@@ -838,11 +847,9 @@ get_more_pages: | |||
838 | } | 847 | } |
839 | 848 | ||
840 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; | 849 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; |
841 | req->r_data_out.num_pages = | 850 | req->r_data_out.length = len; |
842 | calc_pages_for(0, len); | ||
843 | req->r_data_out.alignment = 0; | 851 | req->r_data_out.alignment = 0; |
844 | max_pages = req->r_data_out.num_pages; | 852 | max_pages = calc_pages_for(0, (u64)len); |
845 | |||
846 | alloc_page_vec(fsc, req); | 853 | alloc_page_vec(fsc, req); |
847 | req->r_callback = writepages_finish; | 854 | req->r_callback = writepages_finish; |
848 | req->r_inode = inode; | 855 | req->r_inode = inode; |
@@ -900,7 +907,7 @@ get_more_pages: | |||
900 | locked_pages, offset, len); | 907 | locked_pages, offset, len); |
901 | 908 | ||
902 | /* revise final length, page count */ | 909 | /* revise final length, page count */ |
903 | req->r_data_out.num_pages = locked_pages; | 910 | req->r_data_out.length = len; |
904 | req->r_request_ops[0].extent.length = cpu_to_le64(len); | 911 | req->r_request_ops[0].extent.length = cpu_to_le64(len); |
905 | req->r_request_ops[0].payload_len = cpu_to_le32(len); | 912 | req->r_request_ops[0].payload_len = cpu_to_le32(len); |
906 | req->r_request->hdr.data_len = cpu_to_le32(len); | 913 | req->r_request->hdr.data_len = cpu_to_le32(len); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 501fb37b81a2..0ac6e159bdc6 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -573,7 +573,7 @@ more: | |||
573 | } | 573 | } |
574 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; | 574 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; |
575 | req->r_data_out.pages = pages; | 575 | req->r_data_out.pages = pages; |
576 | req->r_data_out.num_pages = num_pages; | 576 | req->r_data_out.length = len; |
577 | req->r_data_out.alignment = page_align; | 577 | req->r_data_out.alignment = page_align; |
578 | req->r_inode = inode; | 578 | req->r_inode = inode; |
579 | 579 | ||