aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/addr.c33
-rw-r--r--fs/ceph/file.c2
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 */
630static void alloc_page_vec(struct ceph_fs_client *fsc, 636static 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