aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-05 15:46:02 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:18:35 -0400
commit04017e29bbcf0673d8a6af616c56e395d05f5971 (patch)
tree09bd1c613cf85e4410755e2931cf3c21fa5da488
parent90af36022aecdeeb1b9c0755461187de717c86dd (diff)
libceph: make method call data be a separate data item
Right now the data for a method call is specified via a pointer and length, and it's copied--along with the class and method name--into a pagelist data item to be sent to the osd. Instead, encode the data in a data item separate from the class and method names. This will allow large amounts of data to be supplied to methods without copying. Only rbd uses the class functionality right now, and when it really needs this it will probably need to use a page array rather than a page list. But this simple implementation demonstrates the functionality on the osd client, and that's enough for now. This resolves: http://tracker.ceph.com/issues/4104 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--drivers/block/rbd.c15
-rw-r--r--include/linux/ceph/osd_client.h10
-rw-r--r--net/ceph/osd_client.c62
3 files changed, 62 insertions, 25 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 6f7a52cf75c7..11b7987cb75f 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1847,8 +1847,19 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
1847 goto out; 1847 goto out;
1848 1848
1849 osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL, 1849 osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL,
1850 class_name, method_name, 1850 class_name, method_name);
1851 outbound, outbound_size); 1851 if (outbound_size) {
1852 struct ceph_pagelist *pagelist;
1853
1854 pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS);
1855 if (!pagelist)
1856 goto out;
1857
1858 ceph_pagelist_init(pagelist);
1859 ceph_pagelist_append(pagelist, outbound, outbound_size);
1860 osd_req_op_cls_request_data_pagelist(obj_request->osd_req, 0,
1861 pagelist);
1862 }
1852 osd_req_op_cls_response_data_pages(obj_request->osd_req, 0, 1863 osd_req_op_cls_response_data_pages(obj_request->osd_req, 0,
1853 obj_request->pages, inbound_size, 1864 obj_request->pages, inbound_size,
1854 0, false, false); 1865 0, false, false);
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 4ec46c0ceaf7..2a68a7465c18 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -92,10 +92,9 @@ struct ceph_osd_req_op {
92 struct { 92 struct {
93 const char *class_name; 93 const char *class_name;
94 const char *method_name; 94 const char *method_name;
95 const void *request_data;
96 struct ceph_osd_data request_info; 95 struct ceph_osd_data request_info;
96 struct ceph_osd_data request_data;
97 struct ceph_osd_data response_data; 97 struct ceph_osd_data response_data;
98 u32 request_data_len;
99 __u8 class_len; 98 __u8 class_len;
100 __u8 method_len; 99 __u8 method_len;
101 __u8 argc; 100 __u8 argc;
@@ -259,6 +258,9 @@ extern void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *,
259 struct bio *bio, size_t bio_length); 258 struct bio *bio, size_t bio_length);
260#endif /* CONFIG_BLOCK */ 259#endif /* CONFIG_BLOCK */
261 260
261extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *,
262 unsigned int which,
263 struct ceph_pagelist *pagelist);
262extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, 264extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *,
263 unsigned int which, 265 unsigned int which,
264 struct page **pages, u64 length, 266 struct page **pages, u64 length,
@@ -267,9 +269,7 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *,
267 269
268extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, 270extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req,
269 unsigned int which, u16 opcode, 271 unsigned int which, u16 opcode,
270 const char *class, const char *method, 272 const char *class, const char *method);
271 const void *request_data,
272 size_t request_data_size);
273extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req, 273extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req,
274 unsigned int which, u16 opcode, 274 unsigned int which, u16 opcode,
275 u64 cookie, u64 version, int flag); 275 u64 cookie, u64 version, int flag);
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 73227853d845..939be67199ca 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -136,6 +136,16 @@ osd_req_op_cls_request_info(struct ceph_osd_request *osd_req,
136EXPORT_SYMBOL(osd_req_op_cls_request_info); /* ??? */ 136EXPORT_SYMBOL(osd_req_op_cls_request_info); /* ??? */
137 137
138struct ceph_osd_data * 138struct ceph_osd_data *
139osd_req_op_cls_request_data(struct ceph_osd_request *osd_req,
140 unsigned int which)
141{
142 BUG_ON(which >= osd_req->r_num_ops);
143
144 return &osd_req->r_ops[which].cls.request_data;
145}
146EXPORT_SYMBOL(osd_req_op_cls_request_data); /* ??? */
147
148struct ceph_osd_data *
139osd_req_op_cls_response_data(struct ceph_osd_request *osd_req, 149osd_req_op_cls_response_data(struct ceph_osd_request *osd_req,
140 unsigned int which) 150 unsigned int which)
141{ 151{
@@ -192,6 +202,17 @@ static void osd_req_op_cls_request_info_pagelist(
192 ceph_osd_data_pagelist_init(osd_data, pagelist); 202 ceph_osd_data_pagelist_init(osd_data, pagelist);
193} 203}
194 204
205void osd_req_op_cls_request_data_pagelist(
206 struct ceph_osd_request *osd_req,
207 unsigned int which, struct ceph_pagelist *pagelist)
208{
209 struct ceph_osd_data *osd_data;
210
211 osd_data = osd_req_op_cls_request_data(osd_req, which);
212 ceph_osd_data_pagelist_init(osd_data, pagelist);
213}
214EXPORT_SYMBOL(osd_req_op_cls_request_data_pagelist);
215
195void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req, 216void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req,
196 unsigned int which, struct page **pages, u64 length, 217 unsigned int which, struct page **pages, u64 length,
197 u32 alignment, bool pages_from_pool, bool own_pages) 218 u32 alignment, bool pages_from_pool, bool own_pages)
@@ -251,6 +272,7 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
251 break; 272 break;
252 case CEPH_OSD_OP_CALL: 273 case CEPH_OSD_OP_CALL:
253 ceph_osd_data_release(&op->cls.request_info); 274 ceph_osd_data_release(&op->cls.request_info);
275 ceph_osd_data_release(&op->cls.request_data);
254 ceph_osd_data_release(&op->cls.response_data); 276 ceph_osd_data_release(&op->cls.response_data);
255 break; 277 break;
256 default: 278 default:
@@ -492,8 +514,7 @@ void osd_req_op_extent_update(struct ceph_osd_request *osd_req,
492EXPORT_SYMBOL(osd_req_op_extent_update); 514EXPORT_SYMBOL(osd_req_op_extent_update);
493 515
494void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, 516void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
495 u16 opcode, const char *class, const char *method, 517 u16 opcode, const char *class, const char *method)
496 const void *request_data, size_t request_data_size)
497{ 518{
498 struct ceph_osd_req_op *op = osd_req_op_init(osd_req, which, opcode); 519 struct ceph_osd_req_op *op = osd_req_op_init(osd_req, which, opcode);
499 struct ceph_pagelist *pagelist; 520 struct ceph_pagelist *pagelist;
@@ -520,12 +541,6 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
520 ceph_pagelist_append(pagelist, method, size); 541 ceph_pagelist_append(pagelist, method, size);
521 payload_len += size; 542 payload_len += size;
522 543
523 op->cls.request_data = request_data;
524 BUG_ON(request_data_size > (size_t) U32_MAX);
525 op->cls.request_data_len = (u32) request_data_size;
526 ceph_pagelist_append(pagelist, request_data, request_data_size);
527 payload_len += request_data_size;
528
529 osd_req_op_cls_request_info_pagelist(osd_req, which, pagelist); 544 osd_req_op_cls_request_info_pagelist(osd_req, which, pagelist);
530 545
531 op->cls.argc = 0; /* currently unused */ 546 op->cls.argc = 0; /* currently unused */
@@ -576,7 +591,9 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
576 struct ceph_osd_op *dst, unsigned int which) 591 struct ceph_osd_op *dst, unsigned int which)
577{ 592{
578 struct ceph_osd_req_op *src; 593 struct ceph_osd_req_op *src;
594 struct ceph_osd_data *osd_data;
579 u64 request_data_len = 0; 595 u64 request_data_len = 0;
596 u64 data_length;
580 597
581 BUG_ON(which >= req->r_num_ops); 598 BUG_ON(which >= req->r_num_ops);
582 src = &req->r_ops[which]; 599 src = &req->r_ops[which];
@@ -599,22 +616,31 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
599 cpu_to_le64(src->extent.truncate_size); 616 cpu_to_le64(src->extent.truncate_size);
600 dst->extent.truncate_seq = 617 dst->extent.truncate_seq =
601 cpu_to_le32(src->extent.truncate_seq); 618 cpu_to_le32(src->extent.truncate_seq);
619 osd_data = &src->extent.osd_data;
602 if (src->op == CEPH_OSD_OP_WRITE) 620 if (src->op == CEPH_OSD_OP_WRITE)
603 ceph_osdc_msg_data_add(req->r_request, 621 ceph_osdc_msg_data_add(req->r_request, osd_data);
604 &src->extent.osd_data);
605 else 622 else
606 ceph_osdc_msg_data_add(req->r_reply, 623 ceph_osdc_msg_data_add(req->r_reply, osd_data);
607 &src->extent.osd_data);
608 break; 624 break;
609 case CEPH_OSD_OP_CALL: 625 case CEPH_OSD_OP_CALL:
610 dst->cls.class_len = src->cls.class_len; 626 dst->cls.class_len = src->cls.class_len;
611 dst->cls.method_len = src->cls.method_len; 627 dst->cls.method_len = src->cls.method_len;
612 dst->cls.indata_len = cpu_to_le32(src->cls.request_data_len); 628 osd_data = &src->cls.request_info;
613 ceph_osdc_msg_data_add(req->r_reply, &src->cls.response_data); 629 ceph_osdc_msg_data_add(req->r_request, osd_data);
614 ceph_osdc_msg_data_add(req->r_request, &src->cls.request_info); 630 BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGELIST);
615 BUG_ON(src->cls.request_info.type != 631 request_data_len = osd_data->pagelist->length;
616 CEPH_OSD_DATA_TYPE_PAGELIST); 632
617 request_data_len = src->cls.request_info.pagelist->length; 633 osd_data = &src->cls.request_data;
634 data_length = ceph_osd_data_length(osd_data);
635 if (data_length) {
636 BUG_ON(osd_data->type == CEPH_OSD_DATA_TYPE_NONE);
637 dst->cls.indata_len = cpu_to_le32(data_length);
638 ceph_osdc_msg_data_add(req->r_request, osd_data);
639 src->payload_len += data_length;
640 request_data_len += data_length;
641 }
642 osd_data = &src->cls.response_data;
643 ceph_osdc_msg_data_add(req->r_reply, osd_data);
618 break; 644 break;
619 case CEPH_OSD_OP_STARTSYNC: 645 case CEPH_OSD_OP_STARTSYNC:
620 break; 646 break;