aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c8
-rw-r--r--fs/ceph/addr.c55
-rw-r--r--fs/ceph/file.c8
-rw-r--r--include/linux/ceph/osd_client.h24
-rw-r--r--net/ceph/osd_client.c44
5 files changed, 74 insertions, 65 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index b7b7a88d9f68..0e814dfda48e 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1425,12 +1425,12 @@ static struct ceph_osd_request *rbd_osd_req_create(
1425 break; /* Nothing to do */ 1425 break; /* Nothing to do */
1426 case OBJ_REQUEST_BIO: 1426 case OBJ_REQUEST_BIO:
1427 rbd_assert(obj_request->bio_list != NULL); 1427 rbd_assert(obj_request->bio_list != NULL);
1428 osd_req->r_bio = obj_request->bio_list; 1428 osd_req->r_data.bio = obj_request->bio_list;
1429 break; 1429 break;
1430 case OBJ_REQUEST_PAGES: 1430 case OBJ_REQUEST_PAGES:
1431 osd_req->r_pages = obj_request->pages; 1431 osd_req->r_data.pages = obj_request->pages;
1432 osd_req->r_num_pages = obj_request->page_count; 1432 osd_req->r_data.num_pages = obj_request->page_count;
1433 osd_req->r_page_alignment = offset & ~PAGE_MASK; 1433 osd_req->r_data.alignment = offset & ~PAGE_MASK;
1434 break; 1434 break;
1435 } 1435 }
1436 1436
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index e324222acc82..3a1a77b0ae9f 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -243,8 +243,8 @@ 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 for (i = 0; i < req->r_num_pages; i++, bytes -= PAGE_CACHE_SIZE) { 246 for (i = 0; i < req->r_data.num_pages; i++, bytes -= PAGE_CACHE_SIZE) {
247 struct page *page = req->r_pages[i]; 247 struct page *page = req->r_data.pages[i];
248 248
249 if (bytes < (int)PAGE_CACHE_SIZE) { 249 if (bytes < (int)PAGE_CACHE_SIZE) {
250 /* zero (remainder of) page */ 250 /* zero (remainder of) page */
@@ -258,7 +258,7 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg)
258 unlock_page(page); 258 unlock_page(page);
259 page_cache_release(page); 259 page_cache_release(page);
260 } 260 }
261 kfree(req->r_pages); 261 kfree(req->r_data.pages);
262} 262}
263 263
264static void ceph_unlock_page_vector(struct page **pages, int num_pages) 264static void ceph_unlock_page_vector(struct page **pages, int num_pages)
@@ -336,9 +336,9 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
336 } 336 }
337 pages[i] = page; 337 pages[i] = page;
338 } 338 }
339 req->r_pages = pages; 339 req->r_data.pages = pages;
340 req->r_num_pages = nr_pages; 340 req->r_data.num_pages = nr_pages;
341 req->r_page_alignment = 0; 341 req->r_data.alignment = 0;
342 req->r_callback = finish_read; 342 req->r_callback = finish_read;
343 req->r_inode = inode; 343 req->r_inode = inode;
344 344
@@ -374,7 +374,8 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
374 max = (fsc->mount_options->rsize + PAGE_CACHE_SIZE - 1) 374 max = (fsc->mount_options->rsize + PAGE_CACHE_SIZE - 1)
375 >> PAGE_SHIFT; 375 >> PAGE_SHIFT;
376 376
377 dout("readpages %p file %p nr_pages %d max %d\n", inode, file, nr_pages, 377 dout("readpages %p file %p nr_pages %d max %d\n", inode,
378 file, nr_pages,
378 max); 379 max);
379 while (!list_empty(page_list)) { 380 while (!list_empty(page_list)) {
380 rc = start_read(inode, page_list, max); 381 rc = start_read(inode, page_list, max);
@@ -567,7 +568,7 @@ static void writepages_finish(struct ceph_osd_request *req,
567 * raced with a truncation and was adjusted at the osd, 568 * raced with a truncation and was adjusted at the osd,
568 * so don't believe the reply. 569 * so don't believe the reply.
569 */ 570 */
570 wrote = req->r_num_pages; 571 wrote = req->r_data.num_pages;
571 } else { 572 } else {
572 wrote = 0; 573 wrote = 0;
573 mapping_set_error(mapping, rc); 574 mapping_set_error(mapping, rc);
@@ -576,8 +577,8 @@ static void writepages_finish(struct ceph_osd_request *req,
576 inode, rc, bytes, wrote); 577 inode, rc, bytes, wrote);
577 578
578 /* clean all pages */ 579 /* clean all pages */
579 for (i = 0; i < req->r_num_pages; i++) { 580 for (i = 0; i < req->r_data.num_pages; i++) {
580 page = req->r_pages[i]; 581 page = req->r_data.pages[i];
581 BUG_ON(!page); 582 BUG_ON(!page);
582 WARN_ON(!PageUptodate(page)); 583 WARN_ON(!PageUptodate(page));
583 584
@@ -606,31 +607,31 @@ static void writepages_finish(struct ceph_osd_request *req,
606 unlock_page(page); 607 unlock_page(page);
607 } 608 }
608 dout("%p wrote+cleaned %d pages\n", inode, wrote); 609 dout("%p wrote+cleaned %d pages\n", inode, wrote);
609 ceph_put_wrbuffer_cap_refs(ci, req->r_num_pages, snapc); 610 ceph_put_wrbuffer_cap_refs(ci, req->r_data.num_pages, snapc);
610 611
611 ceph_release_pages(req->r_pages, req->r_num_pages); 612 ceph_release_pages(req->r_data.pages, req->r_data.num_pages);
612 if (req->r_pages_from_pool) 613 if (req->r_data.pages_from_pool)
613 mempool_free(req->r_pages, 614 mempool_free(req->r_data.pages,
614 ceph_sb_to_client(inode->i_sb)->wb_pagevec_pool); 615 ceph_sb_to_client(inode->i_sb)->wb_pagevec_pool);
615 else 616 else
616 kfree(req->r_pages); 617 kfree(req->r_data.pages);
617 ceph_osdc_put_request(req); 618 ceph_osdc_put_request(req);
618} 619}
619 620
620/* 621/*
621 * allocate a page vec, either directly, or if necessary, via a the 622 * allocate a page vec, either directly, or if necessary, via a the
622 * mempool. we avoid the mempool if we can because req->r_num_pages 623 * mempool. we avoid the mempool if we can because req->r_data.num_pages
623 * may be less than the maximum write size. 624 * may be less than the maximum write size.
624 */ 625 */
625static void alloc_page_vec(struct ceph_fs_client *fsc, 626static void alloc_page_vec(struct ceph_fs_client *fsc,
626 struct ceph_osd_request *req) 627 struct ceph_osd_request *req)
627{ 628{
628 req->r_pages = kmalloc(sizeof(struct page *) * req->r_num_pages, 629 req->r_data.pages = kmalloc(sizeof(struct page *) * req->r_data.num_pages,
629 GFP_NOFS); 630 GFP_NOFS);
630 if (!req->r_pages) { 631 if (!req->r_data.pages) {
631 req->r_pages = mempool_alloc(fsc->wb_pagevec_pool, GFP_NOFS); 632 req->r_data.pages = mempool_alloc(fsc->wb_pagevec_pool, GFP_NOFS);
632 req->r_pages_from_pool = 1; 633 req->r_data.pages_from_pool = 1;
633 WARN_ON(!req->r_pages); 634 WARN_ON(!req->r_data.pages);
634 } 635 }
635} 636}
636 637
@@ -829,9 +830,9 @@ get_more_pages:
829 break; 830 break;
830 } 831 }
831 832
832 req->r_num_pages = calc_pages_for(0, len); 833 req->r_data.num_pages = calc_pages_for(0, len);
833 req->r_page_alignment = 0; 834 req->r_data.alignment = 0;
834 max_pages = req->r_num_pages; 835 max_pages = req->r_data.num_pages;
835 836
836 alloc_page_vec(fsc, req); 837 alloc_page_vec(fsc, req);
837 req->r_callback = writepages_finish; 838 req->r_callback = writepages_finish;
@@ -853,7 +854,7 @@ get_more_pages:
853 } 854 }
854 855
855 set_page_writeback(page); 856 set_page_writeback(page);
856 req->r_pages[locked_pages] = page; 857 req->r_data.pages[locked_pages] = page;
857 locked_pages++; 858 locked_pages++;
858 next = page->index + 1; 859 next = page->index + 1;
859 } 860 }
@@ -883,14 +884,14 @@ get_more_pages:
883 } 884 }
884 885
885 /* submit the write */ 886 /* submit the write */
886 offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT; 887 offset = req->r_data.pages[0]->index << PAGE_CACHE_SHIFT;
887 len = min((snap_size ? snap_size : i_size_read(inode)) - offset, 888 len = min((snap_size ? snap_size : i_size_read(inode)) - offset,
888 (u64)locked_pages << PAGE_CACHE_SHIFT); 889 (u64)locked_pages << PAGE_CACHE_SHIFT);
889 dout("writepages got %d pages at %llu~%llu\n", 890 dout("writepages got %d pages at %llu~%llu\n",
890 locked_pages, offset, len); 891 locked_pages, offset, len);
891 892
892 /* revise final length, page count */ 893 /* revise final length, page count */
893 req->r_num_pages = locked_pages; 894 req->r_data.num_pages = locked_pages;
894 req->r_request_ops[0].extent.length = cpu_to_le64(len); 895 req->r_request_ops[0].extent.length = cpu_to_le64(len);
895 req->r_request_ops[0].payload_len = cpu_to_le32(len); 896 req->r_request_ops[0].payload_len = cpu_to_le32(len);
896 req->r_request->hdr.data_len = cpu_to_le32(len); 897 req->r_request->hdr.data_len = cpu_to_le32(len);
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index f2754cdb5a03..d35fc05af06f 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -568,12 +568,12 @@ 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_own_pages = 1; 571 req->r_data.own_pages = 1;
572 } 572 }
573 } 573 }
574 req->r_pages = pages; 574 req->r_data.pages = pages;
575 req->r_num_pages = num_pages; 575 req->r_data.num_pages = num_pages;
576 req->r_page_alignment = page_align; 576 req->r_data.alignment = page_align;
577 req->r_inode = inode; 577 req->r_inode = inode;
578 578
579 ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); 579 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 803a9db0b475..600b8278d11e 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -50,6 +50,21 @@ struct ceph_osd {
50 50
51#define CEPH_OSD_MAX_OP 10 51#define CEPH_OSD_MAX_OP 10
52 52
53struct ceph_osd_data {
54 struct {
55 struct {
56 struct page **pages;
57 u32 num_pages;
58 u32 alignment;
59 bool pages_from_pool;
60 bool own_pages;
61 };
62#ifdef CONFIG_BLOCK
63 struct bio *bio;
64#endif /* CONFIG_BLOCK */
65 };
66};
67
53/* an in-flight request */ 68/* an in-flight request */
54struct ceph_osd_request { 69struct ceph_osd_request {
55 u64 r_tid; /* unique for this client */ 70 u64 r_tid; /* unique for this client */
@@ -105,15 +120,8 @@ struct ceph_osd_request {
105 120
106 struct ceph_file_layout r_file_layout; 121 struct ceph_file_layout r_file_layout;
107 struct ceph_snap_context *r_snapc; /* snap context for writes */ 122 struct ceph_snap_context *r_snapc; /* snap context for writes */
108 unsigned r_num_pages; /* size of page array (follows) */
109 unsigned r_page_alignment; /* io offset in first page */
110 struct page **r_pages; /* pages for data payload */
111 int r_pages_from_pool;
112 int r_own_pages; /* if true, i own page list */
113#ifdef CONFIG_BLOCK
114 struct bio *r_bio; /* instead of pages */
115#endif
116 123
124 struct ceph_osd_data r_data;
117 struct ceph_pagelist r_trail; /* trailing part of the data */ 125 struct ceph_pagelist r_trail; /* trailing part of the data */
118}; 126};
119 127
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index de427cc7f6d0..1f8c7a7c203b 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -122,9 +122,9 @@ 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_own_pages) 125 if (req->r_data.own_pages)
126 ceph_release_page_vector(req->r_pages, 126 ceph_release_page_vector(req->r_data.pages,
127 req->r_num_pages); 127 req->r_data.num_pages);
128 ceph_put_snap_context(req->r_snapc); 128 ceph_put_snap_context(req->r_snapc);
129 ceph_pagelist_release(&req->r_trail); 129 ceph_pagelist_release(&req->r_trail);
130 if (req->r_mempool) 130 if (req->r_mempool)
@@ -1739,11 +1739,11 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1739{ 1739{
1740 int rc = 0; 1740 int rc = 0;
1741 1741
1742 req->r_request->pages = req->r_pages; 1742 req->r_request->pages = req->r_data.pages;
1743 req->r_request->page_count = req->r_num_pages; 1743 req->r_request->page_count = req->r_data.num_pages;
1744 req->r_request->page_alignment = req->r_page_alignment; 1744 req->r_request->page_alignment = req->r_data.alignment;
1745#ifdef CONFIG_BLOCK 1745#ifdef CONFIG_BLOCK
1746 req->r_request->bio = req->r_bio; 1746 req->r_request->bio = req->r_data.bio;
1747#endif 1747#endif
1748 req->r_request->trail = &req->r_trail; 1748 req->r_request->trail = &req->r_trail;
1749 1749
@@ -1944,12 +1944,12 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
1944 return PTR_ERR(req); 1944 return PTR_ERR(req);
1945 1945
1946 /* it may be a short read due to an object boundary */ 1946 /* it may be a short read due to an object boundary */
1947 req->r_pages = pages; 1947 req->r_data.pages = pages;
1948 req->r_num_pages = calc_pages_for(page_align, *plen); 1948 req->r_data.num_pages = calc_pages_for(page_align, *plen);
1949 req->r_page_alignment = page_align; 1949 req->r_data.alignment = page_align;
1950 1950
1951 dout("readpages final extent is %llu~%llu (%d pages align %d)\n", 1951 dout("readpages final extent is %llu~%llu (%d pages align %d)\n",
1952 off, *plen, req->r_num_pages, page_align); 1952 off, *plen, req->r_data.num_pages, page_align);
1953 1953
1954 rc = ceph_osdc_start_request(osdc, req, false); 1954 rc = ceph_osdc_start_request(osdc, req, false);
1955 if (!rc) 1955 if (!rc)
@@ -1987,10 +1987,10 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
1987 return PTR_ERR(req); 1987 return PTR_ERR(req);
1988 1988
1989 /* it may be a short write due to an object boundary */ 1989 /* it may be a short write due to an object boundary */
1990 req->r_pages = pages; 1990 req->r_data.pages = pages;
1991 req->r_num_pages = calc_pages_for(page_align, len); 1991 req->r_data.num_pages = calc_pages_for(page_align, len);
1992 req->r_page_alignment = page_align; 1992 req->r_data.alignment = page_align;
1993 dout("writepages %llu~%llu (%d pages)\n", off, len, req->r_num_pages); 1993 dout("writepages %llu~%llu (%d pages)\n", off, len, req->r_data.num_pages);
1994 1994
1995 rc = ceph_osdc_start_request(osdc, req, true); 1995 rc = ceph_osdc_start_request(osdc, req, true);
1996 if (!rc) 1996 if (!rc)
@@ -2083,22 +2083,22 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
2083 m = ceph_msg_get(req->r_reply); 2083 m = ceph_msg_get(req->r_reply);
2084 2084
2085 if (data_len > 0) { 2085 if (data_len > 0) {
2086 int want = calc_pages_for(req->r_page_alignment, data_len); 2086 int want = calc_pages_for(req->r_data.alignment, data_len);
2087 2087
2088 if (req->r_pages && unlikely(req->r_num_pages < want)) { 2088 if (req->r_data.pages && unlikely(req->r_data.num_pages < want)) {
2089 pr_warning("tid %lld reply has %d bytes %d pages, we" 2089 pr_warning("tid %lld reply has %d bytes %d pages, we"
2090 " had only %d pages ready\n", tid, data_len, 2090 " had only %d pages ready\n", tid, data_len,
2091 want, req->r_num_pages); 2091 want, req->r_data.num_pages);
2092 *skip = 1; 2092 *skip = 1;
2093 ceph_msg_put(m); 2093 ceph_msg_put(m);
2094 m = NULL; 2094 m = NULL;
2095 goto out; 2095 goto out;
2096 } 2096 }
2097 m->pages = req->r_pages; 2097 m->pages = req->r_data.pages;
2098 m->page_count = req->r_num_pages; 2098 m->page_count = req->r_data.num_pages;
2099 m->page_alignment = req->r_page_alignment; 2099 m->page_alignment = req->r_data.alignment;
2100#ifdef CONFIG_BLOCK 2100#ifdef CONFIG_BLOCK
2101 m->bio = req->r_bio; 2101 m->bio = req->r_data.bio;
2102#endif 2102#endif
2103 } 2103 }
2104 *skip = 0; 2104 *skip = 0;