diff options
author | Alex Elder <elder@inktank.com> | 2013-03-07 16:38:25 -0500 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:16:36 -0400 |
commit | e0c594878e3211b09208c779df5f996f0b831d9e (patch) | |
tree | 4418813382a61eafd7f3216b8efbc63a1d253f37 /fs | |
parent | 9516e45b25d9967c35d2e798496ec5e590aaa24f (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.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 | ||