aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-03-07 16:38:25 -0500
committerSage Weil <sage@inktank.com>2013-05-02 00:16:36 -0400
commite0c594878e3211b09208c779df5f996f0b831d9e (patch)
tree4418813382a61eafd7f3216b8efbc63a1d253f37 /fs
parent9516e45b25d9967c35d2e798496ec5e590aaa24f (diff)
libceph: record byte count not page count
Record the byte count for an osd request rather than the page count. The number of pages can always be derived from the byte count (and alignment/offset) but the reverse is not true. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'fs')
-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