From: Mike Christie <michaelc@xxxxxxxxxxx> This patch breaks out the code that allocates buffers and executes the request from rbd_obj_method_sync, so future functions in this patchset can use it. It also adds support for OBJ_OP_WRITE requests which is needed for the locking functions which will be added in the next patches. Signed-off-by: Mike Christie <michaelc@xxxxxxxxxxx> --- drivers/block/rbd.c | 156 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 61 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index b40af32..fafe558 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3224,89 +3224,123 @@ static void rbd_dev_header_unwatch_sync(struct rbd_device *rbd_dev) } /* - * Synchronous osd object method call. Returns the number of bytes - * returned in the outbound buffer, or a negative error code. + * Synchronous osd object op call. Returns the number of bytes + * returned in the inbound buffer, or a negative error code. */ -static int rbd_obj_method_sync(struct rbd_device *rbd_dev, - const char *object_name, - const char *class_name, - const char *method_name, - const void *outbound, - size_t outbound_size, - void *inbound, - size_t inbound_size) +static int rbd_obj_request_sync(struct rbd_device *rbd_dev, + struct rbd_obj_request *obj_request, + const void *outbound, size_t outbound_size, + void *inbound, size_t inbound_size) { struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; - struct rbd_obj_request *obj_request; - struct page **pages; - u32 page_count; - int ret; - - /* - * Method calls are ultimately read operations. The result - * should placed into the inbound buffer provided. They - * also supply outbound data--parameters for the object - * method. Currently if this is present it will be a - * snapshot id. - */ - page_count = (u32)calc_pages_for(0, inbound_size); - pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); - if (IS_ERR(pages)) - return PTR_ERR(pages); - - ret = -ENOMEM; - obj_request = rbd_obj_request_create(object_name, 0, inbound_size, - OBJ_REQUEST_PAGES); - if (!obj_request) - goto out; - - obj_request->pages = pages; - obj_request->page_count = page_count; - - obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1, - obj_request); - if (!obj_request->osd_req) - goto out; + struct page **pages = NULL; + u32 page_count = 0; + int ret = -ENOMEM; + u16 op = obj_request->osd_req->r_ops[0].op; + struct ceph_pagelist *pagelist; + + if (inbound_size) { + page_count = (u32)calc_pages_for(0, inbound_size); + pages = ceph_alloc_page_vector(page_count, GFP_NOIO); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + obj_request->pages = pages; + obj_request->page_count = page_count; + + switch (op) { + case CEPH_OSD_OP_CALL: + osd_req_op_cls_response_data_pages(obj_request->osd_req, + 0, pages, + inbound_size, + 0, false, false); + break; + default: + BUG(); + } + } - osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL, - class_name, method_name); if (outbound_size) { - struct ceph_pagelist *pagelist; - - pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS); + pagelist = kmalloc(sizeof (*pagelist), GFP_NOIO); if (!pagelist) - goto out; + goto free_pages; ceph_pagelist_init(pagelist); ceph_pagelist_append(pagelist, outbound, outbound_size); - osd_req_op_cls_request_data_pagelist(obj_request->osd_req, 0, - pagelist); + + switch (op) { + case CEPH_OSD_OP_CALL: + osd_req_op_cls_request_data_pagelist( + obj_request->osd_req, 0, + pagelist); + break; + default: + BUG(); + } } - osd_req_op_cls_response_data_pages(obj_request->osd_req, 0, - obj_request->pages, inbound_size, - 0, false, false); - rbd_osd_req_format_read(obj_request); + + if (inbound_size) + rbd_osd_req_format_read(obj_request); + else + rbd_osd_req_format_write(obj_request); ret = rbd_obj_request_submit(osdc, obj_request); if (ret) - goto out; + goto done; ret = rbd_obj_request_wait(obj_request); if (ret) - goto out; + goto done; ret = obj_request->result; if (ret < 0) - goto out; + goto done; rbd_assert(obj_request->xferred < (u64)INT_MAX); ret = (int)obj_request->xferred; - ceph_copy_from_page_vector(pages, inbound, 0, obj_request->xferred); -out: - if (obj_request) - rbd_obj_request_put(obj_request); - else - ceph_release_page_vector(pages, page_count); + if (inbound_size) + ceph_copy_from_page_vector(pages, inbound, 0, + obj_request->xferred); +done: + return ret; + +free_pages: + ceph_release_page_vector(pages, page_count); + return ret; +} +/* + * Synchronous osd object method call. Returns the number of bytes + * returned in the inbound buffer, or a negative error code. + */ +static int rbd_obj_method_sync(struct rbd_device *rbd_dev, + const char *object_name, + const char *class_name, + const char *method_name, + const void *outbound, + size_t outbound_size, + void *inbound, + size_t inbound_size) +{ + struct rbd_obj_request *obj_request; + int ret = -ENOMEM; + + obj_request = rbd_obj_request_create(object_name, 0, inbound_size, + OBJ_REQUEST_PAGES); + if (!obj_request) + return -ENOMEM; + + obj_request->osd_req = rbd_osd_req_create(rbd_dev, + inbound ? OBJ_OP_READ : OBJ_OP_WRITE, + 1, obj_request); + if (!obj_request->osd_req) + goto out; + + osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL, + class_name, method_name); + ret = rbd_obj_request_sync(rbd_dev, obj_request, outbound, outbound_size, + inbound, inbound_size); +out: + rbd_obj_request_put(obj_request); return ret; } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html