diff options
-rw-r--r-- | drivers/block/rbd.c | 24 | ||||
-rw-r--r-- | fs/ceph/addr.c | 8 | ||||
-rw-r--r-- | fs/ceph/file.c | 5 | ||||
-rw-r--r-- | include/linux/ceph/osd_client.h | 6 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 26 |
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); |
238 | extern void osd_req_op_extent_update(struct ceph_osd_req_op *op, u64 length); | 240 | extern void osd_req_op_extent_update(struct ceph_osd_req_op *op, u64 length); |
241 | extern void osd_req_op_extent_osd_data(struct ceph_osd_req_op *op, | ||
242 | struct ceph_osd_data *osd_data); | ||
239 | extern void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode, | 243 | extern 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); |
247 | extern void osd_req_op_cls_response_data(struct ceph_osd_req_op *op, | ||
248 | struct ceph_osd_data *response_data); | ||
243 | extern void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode, | 249 | extern 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 | } |
373 | EXPORT_SYMBOL(osd_req_op_extent_update); | 373 | EXPORT_SYMBOL(osd_req_op_extent_update); |
374 | 374 | ||
375 | void 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 | } | ||
380 | EXPORT_SYMBOL(osd_req_op_extent_osd_data); | ||
381 | |||
375 | void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode, | 382 | void 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 | } |
407 | EXPORT_SYMBOL(osd_req_op_cls_init); | 414 | EXPORT_SYMBOL(osd_req_op_cls_init); |
408 | 415 | ||
416 | void 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 | } | ||
421 | EXPORT_SYMBOL(osd_req_op_cls_response_data); | ||
422 | |||
409 | void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode, | 423 | void 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 |