aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-03 02:28:58 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:18:14 -0400
commit8c042b0df99cd06ef8473ef6e204b87b3dc80158 (patch)
tree234f410f3253401efa7266cdd67a6e87b22e8bac
parent54d5064912649e296552f298e6472ffd37cd8f90 (diff)
libceph: add data pointers in osd op structures
An extent type osd operation currently implies that there will be corresponding data supplied in the data portion of the request (for write) or response (for read) message. Similarly, an osd class method operation implies a data item will be supplied to receive the response data from the operation. Add a ceph_osd_data pointer to each of those structures, and assign it to point to eithre the incoming or the outgoing data structure in the osd message. The data is not always available when an op is initially set up, so add two new functions to allow setting them after the op has been initialized. Begin to make use of the data item pointer available in the osd operation rather than the request data in or out structure in places where it's convenient. Add some assertions to verify pointers are always set the way they're expected to be. This is a sort of stepping stone toward really moving the data into the osd request ops, to allow for some validation before making that jump. This is the first in a series of patches that resolve: http://tracker.ceph.com/issues/4657 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--drivers/block/rbd.c24
-rw-r--r--fs/ceph/addr.c8
-rw-r--r--fs/ceph/file.c5
-rw-r--r--include/linux/ceph/osd_client.h6
-rw-r--r--net/ceph/osd_client.c26
5 files changed, 59 insertions, 10 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index c12b55559f16..eb64ed0f228f 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1315,23 +1315,39 @@ static void rbd_osd_req_format_op(struct rbd_obj_request *obj_request,
1315 bool write_request) 1315 bool write_request)
1316{ 1316{
1317 struct rbd_img_request *img_request = obj_request->img_request; 1317 struct rbd_img_request *img_request = obj_request->img_request;
1318 struct ceph_osd_request *osd_req = obj_request->osd_req;
1319 struct ceph_osd_data *osd_data = NULL;
1318 struct ceph_snap_context *snapc = NULL; 1320 struct ceph_snap_context *snapc = NULL;
1319 u64 snap_id = CEPH_NOSNAP; 1321 u64 snap_id = CEPH_NOSNAP;
1320 struct timespec *mtime = NULL; 1322 struct timespec *mtime = NULL;
1321 struct timespec now; 1323 struct timespec now;
1322 1324
1323 rbd_assert(obj_request->osd_req != NULL); 1325 rbd_assert(osd_req != NULL);
1324 1326
1325 if (write_request) { 1327 if (write_request) {
1328 osd_data = &osd_req->r_data_out;
1326 now = CURRENT_TIME; 1329 now = CURRENT_TIME;
1327 mtime = &now; 1330 mtime = &now;
1328 if (img_request) 1331 if (img_request)
1329 snapc = img_request->snapc; 1332 snapc = img_request->snapc;
1330 } else if (img_request) { 1333 } else {
1331 snap_id = img_request->snap_id; 1334 osd_data = &osd_req->r_data_in;
1335 if (img_request)
1336 snap_id = img_request->snap_id;
1332 } 1337 }
1338 if (obj_request->type != OBJ_REQUEST_NODATA) {
1339 struct ceph_osd_req_op *op = &obj_request->osd_req->r_ops[0];
1333 1340
1334 ceph_osdc_build_request(obj_request->osd_req, obj_request->offset, 1341 /*
1342 * If it has data, it's either a object class method
1343 * call (cls) or it's an extent operation.
1344 */
1345 if (op->op == CEPH_OSD_OP_CALL)
1346 osd_req_op_cls_response_data(op, osd_data);
1347 else
1348 osd_req_op_extent_osd_data(op, osd_data);
1349 }
1350 ceph_osdc_build_request(osd_req, obj_request->offset,
1335 snapc, snap_id, mtime); 1351 snapc, snap_id, mtime);
1336} 1352}
1337 1353
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index c9da074f0fe6..0ac3a37753cb 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -343,7 +343,8 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
343 } 343 }
344 pages[i] = page; 344 pages[i] = page;
345 } 345 }
346 ceph_osd_data_pages_init(&req->r_data_in, pages, len, 0, 346 BUG_ON(req->r_ops[0].extent.osd_data != &req->r_data_in);
347 ceph_osd_data_pages_init(req->r_ops[0].extent.osd_data, pages, len, 0,
347 false, false); 348 false, false);
348 req->r_callback = finish_read; 349 req->r_callback = finish_read;
349 req->r_inode = inode; 350 req->r_inode = inode;
@@ -916,8 +917,9 @@ get_more_pages:
916 dout("writepages got %d pages at %llu~%llu\n", 917 dout("writepages got %d pages at %llu~%llu\n",
917 locked_pages, offset, len); 918 locked_pages, offset, len);
918 919
919 ceph_osd_data_pages_init(&req->r_data_out, pages, len, 0, 920 BUG_ON(req->r_ops[0].extent.osd_data != &req->r_data_out);
920 !!pool, false); 921 ceph_osd_data_pages_init(req->r_ops[0].extent.osd_data, pages,
922 len, 0, !!pool, false);
921 923
922 pages = NULL; /* request message now owns the pages array */ 924 pages = NULL; /* request message now owns the pages array */
923 pool = NULL; 925 pool = NULL;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index a12f47642c40..cddc10fd7cf9 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -574,8 +574,9 @@ more:
574 own_pages = true; 574 own_pages = true;
575 } 575 }
576 } 576 }
577 ceph_osd_data_pages_init(&req->r_data_out, pages, len, page_align, 577 BUG_ON(req->r_ops[0].extent.osd_data != &req->r_data_out);
578 false, own_pages); 578 ceph_osd_data_pages_init(req->r_ops[0].extent.osd_data, pages, len,
579 page_align, false, own_pages);
579 580
580 /* BUG_ON(vino.snap != CEPH_NOSNAP); */ 581 /* BUG_ON(vino.snap != CEPH_NOSNAP); */
581 ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime); 582 ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index a9c4089894c8..ae5193550fbf 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -87,12 +87,14 @@ struct ceph_osd_req_op {
87 u64 offset, length; 87 u64 offset, length;
88 u64 truncate_size; 88 u64 truncate_size;
89 u32 truncate_seq; 89 u32 truncate_seq;
90 struct ceph_osd_data *osd_data;
90 } extent; 91 } extent;
91 struct { 92 struct {
92 const char *class_name; 93 const char *class_name;
93 const char *method_name; 94 const char *method_name;
94 const void *request_data; 95 const void *request_data;
95 u32 request_data_len; 96 u32 request_data_len;
97 struct ceph_osd_data *response_data;
96 __u8 class_len; 98 __u8 class_len;
97 __u8 method_len; 99 __u8 method_len;
98 __u8 argc; 100 __u8 argc;
@@ -236,10 +238,14 @@ extern void osd_req_op_extent_init(struct ceph_osd_req_op *op, u16 opcode,
236 u64 offset, u64 length, 238 u64 offset, u64 length,
237 u64 truncate_size, u32 truncate_seq); 239 u64 truncate_size, u32 truncate_seq);
238extern void osd_req_op_extent_update(struct ceph_osd_req_op *op, u64 length); 240extern void osd_req_op_extent_update(struct ceph_osd_req_op *op, u64 length);
241extern void osd_req_op_extent_osd_data(struct ceph_osd_req_op *op,
242 struct ceph_osd_data *osd_data);
239extern void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode, 243extern void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode,
240 const char *class, const char *method, 244 const char *class, const char *method,
241 const void *request_data, 245 const void *request_data,
242 size_t request_data_size); 246 size_t request_data_size);
247extern void osd_req_op_cls_response_data(struct ceph_osd_req_op *op,
248 struct ceph_osd_data *response_data);
243extern void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode, 249extern void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode,
244 u64 cookie, u64 version, int flag); 250 u64 cookie, u64 version, int flag);
245 251
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 87fcf0b795c0..23491e92b229 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -372,6 +372,13 @@ void osd_req_op_extent_update(struct ceph_osd_req_op *op, u64 length)
372} 372}
373EXPORT_SYMBOL(osd_req_op_extent_update); 373EXPORT_SYMBOL(osd_req_op_extent_update);
374 374
375void osd_req_op_extent_osd_data(struct ceph_osd_req_op *op,
376 struct ceph_osd_data *osd_data)
377{
378 op->extent.osd_data = osd_data;
379}
380EXPORT_SYMBOL(osd_req_op_extent_osd_data);
381
375void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode, 382void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode,
376 const char *class, const char *method, 383 const char *class, const char *method,
377 const void *request_data, size_t request_data_size) 384 const void *request_data, size_t request_data_size)
@@ -406,6 +413,13 @@ void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode,
406} 413}
407EXPORT_SYMBOL(osd_req_op_cls_init); 414EXPORT_SYMBOL(osd_req_op_cls_init);
408 415
416void osd_req_op_cls_response_data(struct ceph_osd_req_op *op,
417 struct ceph_osd_data *response_data)
418{
419 op->cls.response_data = response_data;
420}
421EXPORT_SYMBOL(osd_req_op_cls_response_data);
422
409void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode, 423void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode,
410 u64 cookie, u64 version, int flag) 424 u64 cookie, u64 version, int flag)
411{ 425{
@@ -449,6 +463,10 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
449 cpu_to_le64(src->extent.truncate_size); 463 cpu_to_le64(src->extent.truncate_size);
450 dst->extent.truncate_seq = 464 dst->extent.truncate_seq =
451 cpu_to_le32(src->extent.truncate_seq); 465 cpu_to_le32(src->extent.truncate_seq);
466 if (src->op == CEPH_OSD_OP_WRITE)
467 WARN_ON(src->extent.osd_data != &req->r_data_out);
468 else
469 WARN_ON(src->extent.osd_data != &req->r_data_in);
452 break; 470 break;
453 case CEPH_OSD_OP_CALL: 471 case CEPH_OSD_OP_CALL:
454 pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS); 472 pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS);
@@ -464,8 +482,9 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
464 src->cls.method_len); 482 src->cls.method_len);
465 ceph_pagelist_append(pagelist, src->cls.request_data, 483 ceph_pagelist_append(pagelist, src->cls.request_data,
466 src->cls.request_data_len); 484 src->cls.request_data_len);
467
468 ceph_osd_data_pagelist_init(&req->r_data_out, pagelist); 485 ceph_osd_data_pagelist_init(&req->r_data_out, pagelist);
486
487 WARN_ON(src->cls.response_data != &req->r_data_in);
469 request_data_len = pagelist->length; 488 request_data_len = pagelist->length;
470 break; 489 break;
471 case CEPH_OSD_OP_STARTSYNC: 490 case CEPH_OSD_OP_STARTSYNC:
@@ -609,6 +628,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
609 bool use_mempool) 628 bool use_mempool)
610{ 629{
611 struct ceph_osd_request *req; 630 struct ceph_osd_request *req;
631 struct ceph_osd_data *osd_data;
612 struct ceph_osd_req_op *op; 632 struct ceph_osd_req_op *op;
613 u64 objnum = 0; 633 u64 objnum = 0;
614 u64 objoff = 0; 634 u64 objoff = 0;
@@ -623,6 +643,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
623 GFP_NOFS); 643 GFP_NOFS);
624 if (!req) 644 if (!req)
625 return ERR_PTR(-ENOMEM); 645 return ERR_PTR(-ENOMEM);
646 osd_data = opcode == CEPH_OSD_OP_WRITE ? &req->r_data_out
647 : &req->r_data_in;
626 648
627 req->r_flags = flags; 649 req->r_flags = flags;
628 650
@@ -646,6 +668,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
646 op = &req->r_ops[0]; 668 op = &req->r_ops[0];
647 osd_req_op_extent_init(op, opcode, objoff, objlen, 669 osd_req_op_extent_init(op, opcode, objoff, objlen,
648 truncate_size, truncate_seq); 670 truncate_size, truncate_seq);
671 osd_req_op_extent_osd_data(op, osd_data);
672
649 /* 673 /*
650 * A second op in the ops array means the caller wants to 674 * A second op in the ops array means the caller wants to
651 * also issue a include a 'startsync' command so that the 675 * also issue a include a 'startsync' command so that the