diff options
-rw-r--r-- | drivers/block/rbd.c | 18 | ||||
-rw-r--r-- | fs/ceph/addr.c | 67 | ||||
-rw-r--r-- | fs/ceph/file.c | 10 | ||||
-rw-r--r-- | include/linux/ceph/osd_client.h | 5 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 83 |
5 files changed, 105 insertions, 78 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index f189bc2909b0..3f69eb1bc656 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -1398,6 +1398,7 @@ static struct ceph_osd_request *rbd_osd_req_create( | |||
1398 | struct ceph_snap_context *snapc = NULL; | 1398 | struct ceph_snap_context *snapc = NULL; |
1399 | struct ceph_osd_client *osdc; | 1399 | struct ceph_osd_client *osdc; |
1400 | struct ceph_osd_request *osd_req; | 1400 | struct ceph_osd_request *osd_req; |
1401 | struct ceph_osd_data *osd_data; | ||
1401 | struct timespec now; | 1402 | struct timespec now; |
1402 | struct timespec *mtime; | 1403 | struct timespec *mtime; |
1403 | u64 snap_id = CEPH_NOSNAP; | 1404 | u64 snap_id = CEPH_NOSNAP; |
@@ -1418,6 +1419,7 @@ static struct ceph_osd_request *rbd_osd_req_create( | |||
1418 | osd_req = ceph_osdc_alloc_request(osdc, snapc, 1, false, GFP_ATOMIC); | 1419 | osd_req = ceph_osdc_alloc_request(osdc, snapc, 1, false, GFP_ATOMIC); |
1419 | if (!osd_req) | 1420 | if (!osd_req) |
1420 | return NULL; /* ENOMEM */ | 1421 | return NULL; /* ENOMEM */ |
1422 | osd_data = write_request ? &osd_req->r_data_out : &osd_req->r_data_in; | ||
1421 | 1423 | ||
1422 | rbd_assert(obj_request_type_valid(obj_request->type)); | 1424 | rbd_assert(obj_request_type_valid(obj_request->type)); |
1423 | switch (obj_request->type) { | 1425 | switch (obj_request->type) { |
@@ -1425,16 +1427,16 @@ static struct ceph_osd_request *rbd_osd_req_create( | |||
1425 | break; /* Nothing to do */ | 1427 | break; /* Nothing to do */ |
1426 | case OBJ_REQUEST_BIO: | 1428 | case OBJ_REQUEST_BIO: |
1427 | rbd_assert(obj_request->bio_list != NULL); | 1429 | rbd_assert(obj_request->bio_list != NULL); |
1428 | osd_req->r_data.type = CEPH_OSD_DATA_TYPE_BIO; | 1430 | osd_data->type = CEPH_OSD_DATA_TYPE_BIO; |
1429 | osd_req->r_data.bio = obj_request->bio_list; | 1431 | osd_data->bio = obj_request->bio_list; |
1430 | break; | 1432 | break; |
1431 | case OBJ_REQUEST_PAGES: | 1433 | case OBJ_REQUEST_PAGES: |
1432 | osd_req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; | 1434 | osd_data->type = CEPH_OSD_DATA_TYPE_PAGES; |
1433 | osd_req->r_data.pages = obj_request->pages; | 1435 | osd_data->pages = obj_request->pages; |
1434 | osd_req->r_data.num_pages = obj_request->page_count; | 1436 | osd_data->num_pages = obj_request->page_count; |
1435 | osd_req->r_data.alignment = offset & ~PAGE_MASK; | 1437 | osd_data->alignment = offset & ~PAGE_MASK; |
1436 | osd_req->r_data.pages_from_pool = false; | 1438 | osd_data->pages_from_pool = false; |
1437 | osd_req->r_data.own_pages = false; | 1439 | osd_data->own_pages = false; |
1438 | break; | 1440 | break; |
1439 | } | 1441 | } |
1440 | 1442 | ||
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 276fe96f12e3..c117c51741d5 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -243,9 +243,9 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg) | |||
243 | dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes); | 243 | dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes); |
244 | 244 | ||
245 | /* unlock all pages, zeroing any data we didn't read */ | 245 | /* unlock all pages, zeroing any data we didn't read */ |
246 | BUG_ON(req->r_data.type != CEPH_OSD_DATA_TYPE_PAGES); | 246 | BUG_ON(req->r_data_in.type != CEPH_OSD_DATA_TYPE_PAGES); |
247 | for (i = 0; i < req->r_data.num_pages; i++, bytes -= PAGE_CACHE_SIZE) { | 247 | for (i = 0; i < req->r_data_in.num_pages; i++) { |
248 | struct page *page = req->r_data.pages[i]; | 248 | struct page *page = req->r_data_in.pages[i]; |
249 | 249 | ||
250 | if (bytes < (int)PAGE_CACHE_SIZE) { | 250 | if (bytes < (int)PAGE_CACHE_SIZE) { |
251 | /* zero (remainder of) page */ | 251 | /* zero (remainder of) page */ |
@@ -258,8 +258,9 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg) | |||
258 | SetPageUptodate(page); | 258 | SetPageUptodate(page); |
259 | unlock_page(page); | 259 | unlock_page(page); |
260 | page_cache_release(page); | 260 | page_cache_release(page); |
261 | bytes -= PAGE_CACHE_SIZE; | ||
261 | } | 262 | } |
262 | kfree(req->r_data.pages); | 263 | kfree(req->r_data_in.pages); |
263 | } | 264 | } |
264 | 265 | ||
265 | static void ceph_unlock_page_vector(struct page **pages, int num_pages) | 266 | static void ceph_unlock_page_vector(struct page **pages, int num_pages) |
@@ -337,10 +338,10 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) | |||
337 | } | 338 | } |
338 | pages[i] = page; | 339 | pages[i] = page; |
339 | } | 340 | } |
340 | req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; | 341 | req->r_data_in.type = CEPH_OSD_DATA_TYPE_PAGES; |
341 | req->r_data.pages = pages; | 342 | req->r_data_in.pages = pages; |
342 | req->r_data.num_pages = nr_pages; | 343 | req->r_data_in.num_pages = nr_pages; |
343 | req->r_data.alignment = 0; | 344 | req->r_data_in.alignment = 0; |
344 | req->r_callback = finish_read; | 345 | req->r_callback = finish_read; |
345 | req->r_inode = inode; | 346 | req->r_inode = inode; |
346 | 347 | ||
@@ -563,7 +564,7 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
563 | long writeback_stat; | 564 | long writeback_stat; |
564 | unsigned issued = ceph_caps_issued(ci); | 565 | unsigned issued = ceph_caps_issued(ci); |
565 | 566 | ||
566 | BUG_ON(req->r_data.type != CEPH_OSD_DATA_TYPE_PAGES); | 567 | BUG_ON(req->r_data_out.type != CEPH_OSD_DATA_TYPE_PAGES); |
567 | if (rc >= 0) { | 568 | if (rc >= 0) { |
568 | /* | 569 | /* |
569 | * Assume we wrote the pages we originally sent. The | 570 | * Assume we wrote the pages we originally sent. The |
@@ -571,7 +572,7 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
571 | * raced with a truncation and was adjusted at the osd, | 572 | * raced with a truncation and was adjusted at the osd, |
572 | * so don't believe the reply. | 573 | * so don't believe the reply. |
573 | */ | 574 | */ |
574 | wrote = req->r_data.num_pages; | 575 | wrote = req->r_data_out.num_pages; |
575 | } else { | 576 | } else { |
576 | wrote = 0; | 577 | wrote = 0; |
577 | mapping_set_error(mapping, rc); | 578 | mapping_set_error(mapping, rc); |
@@ -580,8 +581,8 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
580 | inode, rc, bytes, wrote); | 581 | inode, rc, bytes, wrote); |
581 | 582 | ||
582 | /* clean all pages */ | 583 | /* clean all pages */ |
583 | for (i = 0; i < req->r_data.num_pages; i++) { | 584 | for (i = 0; i < req->r_data_out.num_pages; i++) { |
584 | page = req->r_data.pages[i]; | 585 | page = req->r_data_out.pages[i]; |
585 | BUG_ON(!page); | 586 | BUG_ON(!page); |
586 | WARN_ON(!PageUptodate(page)); | 587 | WARN_ON(!PageUptodate(page)); |
587 | 588 | ||
@@ -610,31 +611,34 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
610 | unlock_page(page); | 611 | unlock_page(page); |
611 | } | 612 | } |
612 | dout("%p wrote+cleaned %d pages\n", inode, wrote); | 613 | dout("%p wrote+cleaned %d pages\n", inode, wrote); |
613 | ceph_put_wrbuffer_cap_refs(ci, req->r_data.num_pages, snapc); | 614 | ceph_put_wrbuffer_cap_refs(ci, req->r_data_out.num_pages, snapc); |
614 | 615 | ||
615 | ceph_release_pages(req->r_data.pages, req->r_data.num_pages); | 616 | ceph_release_pages(req->r_data_out.pages, req->r_data_out.num_pages); |
616 | if (req->r_data.pages_from_pool) | 617 | if (req->r_data_out.pages_from_pool) |
617 | mempool_free(req->r_data.pages, | 618 | mempool_free(req->r_data_out.pages, |
618 | ceph_sb_to_client(inode->i_sb)->wb_pagevec_pool); | 619 | ceph_sb_to_client(inode->i_sb)->wb_pagevec_pool); |
619 | else | 620 | else |
620 | kfree(req->r_data.pages); | 621 | kfree(req->r_data_out.pages); |
621 | ceph_osdc_put_request(req); | 622 | ceph_osdc_put_request(req); |
622 | } | 623 | } |
623 | 624 | ||
624 | /* | 625 | /* |
625 | * allocate a page vec, either directly, or if necessary, via a the | 626 | * allocate a page vec, either directly, or if necessary, via a the |
626 | * mempool. we avoid the mempool if we can because req->r_data.num_pages | 627 | * mempool. we avoid the mempool if we can because req->r_data_out.num_pages |
627 | * may be less than the maximum write size. | 628 | * may be less than the maximum write size. |
628 | */ | 629 | */ |
629 | static void alloc_page_vec(struct ceph_fs_client *fsc, | 630 | static void alloc_page_vec(struct ceph_fs_client *fsc, |
630 | struct ceph_osd_request *req) | 631 | struct ceph_osd_request *req) |
631 | { | 632 | { |
632 | req->r_data.pages = kmalloc(sizeof(struct page *) * req->r_data.num_pages, | 633 | size_t size; |
633 | GFP_NOFS); | 634 | |
634 | if (!req->r_data.pages) { | 635 | size = sizeof (struct page *) * req->r_data_out.num_pages; |
635 | req->r_data.pages = mempool_alloc(fsc->wb_pagevec_pool, GFP_NOFS); | 636 | req->r_data_out.pages = kmalloc(size, GFP_NOFS); |
636 | req->r_data.pages_from_pool = 1; | 637 | if (!req->r_data_out.pages) { |
637 | WARN_ON(!req->r_data.pages); | 638 | req->r_data_out.pages = mempool_alloc(fsc->wb_pagevec_pool, |
639 | GFP_NOFS); | ||
640 | req->r_data_out.pages_from_pool = 1; | ||
641 | WARN_ON(!req->r_data_out.pages); | ||
638 | } | 642 | } |
639 | } | 643 | } |
640 | 644 | ||
@@ -833,10 +837,11 @@ get_more_pages: | |||
833 | break; | 837 | break; |
834 | } | 838 | } |
835 | 839 | ||
836 | req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; | 840 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; |
837 | req->r_data.num_pages = calc_pages_for(0, len); | 841 | req->r_data_out.num_pages = |
838 | req->r_data.alignment = 0; | 842 | calc_pages_for(0, len); |
839 | max_pages = req->r_data.num_pages; | 843 | req->r_data_out.alignment = 0; |
844 | max_pages = req->r_data_out.num_pages; | ||
840 | 845 | ||
841 | alloc_page_vec(fsc, req); | 846 | alloc_page_vec(fsc, req); |
842 | req->r_callback = writepages_finish; | 847 | req->r_callback = writepages_finish; |
@@ -858,7 +863,7 @@ get_more_pages: | |||
858 | } | 863 | } |
859 | 864 | ||
860 | set_page_writeback(page); | 865 | set_page_writeback(page); |
861 | req->r_data.pages[locked_pages] = page; | 866 | req->r_data_out.pages[locked_pages] = page; |
862 | locked_pages++; | 867 | locked_pages++; |
863 | next = page->index + 1; | 868 | next = page->index + 1; |
864 | } | 869 | } |
@@ -888,14 +893,14 @@ get_more_pages: | |||
888 | } | 893 | } |
889 | 894 | ||
890 | /* submit the write */ | 895 | /* submit the write */ |
891 | offset = req->r_data.pages[0]->index << PAGE_CACHE_SHIFT; | 896 | offset = req->r_data_out.pages[0]->index << PAGE_CACHE_SHIFT; |
892 | len = min((snap_size ? snap_size : i_size_read(inode)) - offset, | 897 | len = min((snap_size ? snap_size : i_size_read(inode)) - offset, |
893 | (u64)locked_pages << PAGE_CACHE_SHIFT); | 898 | (u64)locked_pages << PAGE_CACHE_SHIFT); |
894 | dout("writepages got %d pages at %llu~%llu\n", | 899 | dout("writepages got %d pages at %llu~%llu\n", |
895 | locked_pages, offset, len); | 900 | locked_pages, offset, len); |
896 | 901 | ||
897 | /* revise final length, page count */ | 902 | /* revise final length, page count */ |
898 | req->r_data.num_pages = locked_pages; | 903 | req->r_data_out.num_pages = locked_pages; |
899 | req->r_request_ops[0].extent.length = cpu_to_le64(len); | 904 | req->r_request_ops[0].extent.length = cpu_to_le64(len); |
900 | req->r_request_ops[0].payload_len = cpu_to_le32(len); | 905 | req->r_request_ops[0].payload_len = cpu_to_le32(len); |
901 | req->r_request->hdr.data_len = cpu_to_le32(len); | 906 | req->r_request->hdr.data_len = cpu_to_le32(len); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 3643a386ab23..501fb37b81a2 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -568,13 +568,13 @@ more: | |||
568 | if ((file->f_flags & O_SYNC) == 0) { | 568 | if ((file->f_flags & O_SYNC) == 0) { |
569 | /* get a second commit callback */ | 569 | /* get a second commit callback */ |
570 | req->r_safe_callback = sync_write_commit; | 570 | req->r_safe_callback = sync_write_commit; |
571 | req->r_data.own_pages = 1; | 571 | req->r_data_out.own_pages = 1; |
572 | } | 572 | } |
573 | } | 573 | } |
574 | req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; | 574 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; |
575 | req->r_data.pages = pages; | 575 | req->r_data_out.pages = pages; |
576 | req->r_data.num_pages = num_pages; | 576 | req->r_data_out.num_pages = num_pages; |
577 | req->r_data.alignment = page_align; | 577 | req->r_data_out.alignment = page_align; |
578 | req->r_inode = inode; | 578 | req->r_inode = inode; |
579 | 579 | ||
580 | ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); | 580 | ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); |
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 56604b33dc3c..40e02603723d 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h | |||
@@ -130,8 +130,9 @@ struct ceph_osd_request { | |||
130 | struct ceph_file_layout r_file_layout; | 130 | struct ceph_file_layout r_file_layout; |
131 | struct ceph_snap_context *r_snapc; /* snap context for writes */ | 131 | struct ceph_snap_context *r_snapc; /* snap context for writes */ |
132 | 132 | ||
133 | struct ceph_osd_data r_data; | 133 | struct ceph_osd_data r_data_in; |
134 | struct ceph_pagelist r_trail; /* trailing part of the data */ | 134 | struct ceph_osd_data r_data_out; |
135 | struct ceph_pagelist r_trail; /* trailing part of data out */ | ||
135 | }; | 136 | }; |
136 | 137 | ||
137 | struct ceph_osd_event { | 138 | struct ceph_osd_event { |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 591e1b0cccbe..f9cf44504484 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -122,10 +122,16 @@ void ceph_osdc_release_request(struct kref *kref) | |||
122 | } | 122 | } |
123 | if (req->r_reply) | 123 | if (req->r_reply) |
124 | ceph_msg_put(req->r_reply); | 124 | ceph_msg_put(req->r_reply); |
125 | if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES && | 125 | |
126 | req->r_data.own_pages) | 126 | if (req->r_data_in.type == CEPH_OSD_DATA_TYPE_PAGES && |
127 | ceph_release_page_vector(req->r_data.pages, | 127 | req->r_data_in.own_pages) |
128 | req->r_data.num_pages); | 128 | ceph_release_page_vector(req->r_data_in.pages, |
129 | req->r_data_in.num_pages); | ||
130 | if (req->r_data_out.type == CEPH_OSD_DATA_TYPE_PAGES && | ||
131 | req->r_data_out.own_pages) | ||
132 | ceph_release_page_vector(req->r_data_out.pages, | ||
133 | req->r_data_out.num_pages); | ||
134 | |||
129 | ceph_put_snap_context(req->r_snapc); | 135 | ceph_put_snap_context(req->r_snapc); |
130 | ceph_pagelist_release(&req->r_trail); | 136 | ceph_pagelist_release(&req->r_trail); |
131 | if (req->r_mempool) | 137 | if (req->r_mempool) |
@@ -189,7 +195,8 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, | |||
189 | } | 195 | } |
190 | req->r_reply = msg; | 196 | req->r_reply = msg; |
191 | 197 | ||
192 | req->r_data.type = CEPH_OSD_DATA_TYPE_NONE; | 198 | req->r_data_in.type = CEPH_OSD_DATA_TYPE_NONE; |
199 | req->r_data_out.type = CEPH_OSD_DATA_TYPE_NONE; | ||
193 | ceph_pagelist_init(&req->r_trail); | 200 | ceph_pagelist_init(&req->r_trail); |
194 | 201 | ||
195 | /* create request message; allow space for oid */ | 202 | /* create request message; allow space for oid */ |
@@ -1740,17 +1747,21 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, | |||
1740 | bool nofail) | 1747 | bool nofail) |
1741 | { | 1748 | { |
1742 | int rc = 0; | 1749 | int rc = 0; |
1750 | struct ceph_osd_data *osd_data; | ||
1751 | |||
1752 | /* Set up outgoing data */ | ||
1743 | 1753 | ||
1744 | if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES) { | 1754 | osd_data = &req->r_data_out; |
1745 | req->r_request->pages = req->r_data.pages; | 1755 | if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) { |
1746 | req->r_request->page_count = req->r_data.num_pages; | 1756 | req->r_request->pages = osd_data->pages; |
1747 | req->r_request->page_alignment = req->r_data.alignment; | 1757 | req->r_request->page_count = osd_data->num_pages; |
1758 | req->r_request->page_alignment = osd_data->alignment; | ||
1748 | #ifdef CONFIG_BLOCK | 1759 | #ifdef CONFIG_BLOCK |
1749 | } else if (req->r_data.type == CEPH_OSD_DATA_TYPE_BIO) { | 1760 | } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) { |
1750 | req->r_request->bio = req->r_data.bio; | 1761 | req->r_request->bio = osd_data->bio; |
1751 | #endif | 1762 | #endif |
1752 | } else { | 1763 | } else { |
1753 | pr_err("unknown request data type %d\n", req->r_data.type); | 1764 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_NONE); |
1754 | } | 1765 | } |
1755 | req->r_request->trail = &req->r_trail; | 1766 | req->r_request->trail = &req->r_trail; |
1756 | 1767 | ||
@@ -1939,6 +1950,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, | |||
1939 | struct page **pages, int num_pages, int page_align) | 1950 | struct page **pages, int num_pages, int page_align) |
1940 | { | 1951 | { |
1941 | struct ceph_osd_request *req; | 1952 | struct ceph_osd_request *req; |
1953 | struct ceph_osd_data *osd_data; | ||
1942 | int rc = 0; | 1954 | int rc = 0; |
1943 | 1955 | ||
1944 | dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino, | 1956 | dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino, |
@@ -1951,13 +1963,15 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, | |||
1951 | return PTR_ERR(req); | 1963 | return PTR_ERR(req); |
1952 | 1964 | ||
1953 | /* it may be a short read due to an object boundary */ | 1965 | /* it may be a short read due to an object boundary */ |
1954 | req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; | 1966 | |
1955 | req->r_data.pages = pages; | 1967 | osd_data = &req->r_data_in; |
1956 | req->r_data.num_pages = calc_pages_for(page_align, *plen); | 1968 | osd_data->type = CEPH_OSD_DATA_TYPE_PAGES; |
1957 | req->r_data.alignment = page_align; | 1969 | osd_data->pages = pages; |
1970 | osd_data->num_pages = calc_pages_for(page_align, *plen); | ||
1971 | osd_data->alignment = page_align; | ||
1958 | 1972 | ||
1959 | dout("readpages final extent is %llu~%llu (%d pages align %d)\n", | 1973 | dout("readpages final extent is %llu~%llu (%d pages align %d)\n", |
1960 | off, *plen, req->r_data.num_pages, page_align); | 1974 | off, *plen, osd_data->num_pages, page_align); |
1961 | 1975 | ||
1962 | rc = ceph_osdc_start_request(osdc, req, false); | 1976 | rc = ceph_osdc_start_request(osdc, req, false); |
1963 | if (!rc) | 1977 | if (!rc) |
@@ -1981,6 +1995,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, | |||
1981 | struct page **pages, int num_pages) | 1995 | struct page **pages, int num_pages) |
1982 | { | 1996 | { |
1983 | struct ceph_osd_request *req; | 1997 | struct ceph_osd_request *req; |
1998 | struct ceph_osd_data *osd_data; | ||
1984 | int rc = 0; | 1999 | int rc = 0; |
1985 | int page_align = off & ~PAGE_MASK; | 2000 | int page_align = off & ~PAGE_MASK; |
1986 | 2001 | ||
@@ -1995,11 +2010,13 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, | |||
1995 | return PTR_ERR(req); | 2010 | return PTR_ERR(req); |
1996 | 2011 | ||
1997 | /* it may be a short write due to an object boundary */ | 2012 | /* it may be a short write due to an object boundary */ |
1998 | req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; | 2013 | osd_data = &req->r_data_out; |
1999 | req->r_data.pages = pages; | 2014 | osd_data->type = CEPH_OSD_DATA_TYPE_PAGES; |
2000 | req->r_data.num_pages = calc_pages_for(page_align, len); | 2015 | osd_data->pages = pages; |
2001 | req->r_data.alignment = page_align; | 2016 | osd_data->num_pages = calc_pages_for(page_align, len); |
2002 | dout("writepages %llu~%llu (%d pages)\n", off, len, req->r_data.num_pages); | 2017 | osd_data->alignment = page_align; |
2018 | dout("writepages %llu~%llu (%d pages)\n", off, len, | ||
2019 | osd_data->num_pages); | ||
2003 | 2020 | ||
2004 | rc = ceph_osdc_start_request(osdc, req, true); | 2021 | rc = ceph_osdc_start_request(osdc, req, true); |
2005 | if (!rc) | 2022 | if (!rc) |
@@ -2092,28 +2109,30 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, | |||
2092 | m = ceph_msg_get(req->r_reply); | 2109 | m = ceph_msg_get(req->r_reply); |
2093 | 2110 | ||
2094 | if (data_len > 0) { | 2111 | if (data_len > 0) { |
2095 | if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES) { | 2112 | struct ceph_osd_data *osd_data = &req->r_data_in; |
2113 | |||
2114 | if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) { | ||
2096 | int want; | 2115 | int want; |
2097 | 2116 | ||
2098 | want = calc_pages_for(req->r_data.alignment, data_len); | 2117 | want = calc_pages_for(osd_data->alignment, data_len); |
2099 | if (req->r_data.pages && | 2118 | if (osd_data->pages && |
2100 | unlikely(req->r_data.num_pages < want)) { | 2119 | unlikely(osd_data->num_pages < want)) { |
2101 | 2120 | ||
2102 | pr_warning("tid %lld reply has %d bytes %d " | 2121 | pr_warning("tid %lld reply has %d bytes %d " |
2103 | "pages, we had only %d pages ready\n", | 2122 | "pages, we had only %d pages ready\n", |
2104 | tid, data_len, want, | 2123 | tid, data_len, want, |
2105 | req->r_data.num_pages); | 2124 | osd_data->num_pages); |
2106 | *skip = 1; | 2125 | *skip = 1; |
2107 | ceph_msg_put(m); | 2126 | ceph_msg_put(m); |
2108 | m = NULL; | 2127 | m = NULL; |
2109 | goto out; | 2128 | goto out; |
2110 | } | 2129 | } |
2111 | m->pages = req->r_data.pages; | 2130 | m->pages = osd_data->pages; |
2112 | m->page_count = req->r_data.num_pages; | 2131 | m->page_count = osd_data->num_pages; |
2113 | m->page_alignment = req->r_data.alignment; | 2132 | m->page_alignment = osd_data->alignment; |
2114 | #ifdef CONFIG_BLOCK | 2133 | #ifdef CONFIG_BLOCK |
2115 | } else if (req->r_data.type == CEPH_OSD_DATA_TYPE_BIO) { | 2134 | } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) { |
2116 | m->bio = req->r_data.bio; | 2135 | m->bio = osd_data->bio; |
2117 | #endif | 2136 | #endif |
2118 | } | 2137 | } |
2119 | } | 2138 | } |