Re: [PATCH 11/12, v2] rbd: implement sync method with new code
With the version parameter removed now or in a later patch: Reviewed-by: Josh Durgin On 01/24/2013 08:36 AM, Alex Elder wrote: Reimplement synchronous object method calls using the new request tracking code. Use the name rbd_obj_method_sync() Signed-off-by: Alex Elder --- drivers/block/rbd.c | 111 +++ 1 file changed, 94 insertions(+), 17 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 48650d1..5ad2ac2 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -1413,6 +1413,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, case CEPH_OSD_OP_WRITE: rbd_osd_write_callback(obj_request, op); break; + case CEPH_OSD_OP_CALL: case CEPH_OSD_OP_NOTIFY_ACK: case CEPH_OSD_OP_WATCH: rbd_osd_trivial_callback(obj_request, op); @@ -1903,6 +1904,81 @@ done: return ret; } +/* + * Synchronous osd object method call + */ +static int rbd_obj_method_sync(struct rbd_device *rbd_dev, +const char *object_name, +const char *class_name, +const char *method_name, +const char *outbound, +size_t outbound_size, +char *inbound, +size_t inbound_size, +u64 *version) You can get rid of the version parameter. It's not useful to any current or planned rbd code that I can think of. +{ + struct rbd_obj_request *obj_request; + struct ceph_osd_client *osdc; + struct ceph_osd_req_op *op; + struct page **pages; + u32 page_count; + int ret; + + /* +* Method calls are ultimately read operations but they +* don't involve object data (so no offset or length). +* 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, 0, obj_req_pages); + if (!obj_request) + goto out; + + obj_request->pages = pages; + obj_request->page_count = page_count; + + op = rbd_osd_req_op_create(CEPH_OSD_OP_CALL, class_name, + method_name, outbound, outbound_size); + if (!op) + goto out; + obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, + obj_request, op); + rbd_osd_req_op_destroy(op); + if (!obj_request->osd_req) + goto out; + + osdc = &rbd_dev->rbd_client->client->osdc; + ret = rbd_obj_request_submit(osdc, obj_request); + if (ret) + goto out; + ret = rbd_obj_request_wait(obj_request); + if (ret) + goto out; + + ret = obj_request->result; + if (ret < 0) + goto out; + ret = ceph_copy_from_page_vector(pages, inbound, 0, + obj_request->xferred); + if (version) + *version = obj_request->version; Here too +out: + if (obj_request) + rbd_obj_request_put(obj_request); + else + ceph_release_page_vector(pages, page_count); + + return ret; +} + static void rbd_request_fn(struct request_queue *q) { struct rbd_device *rbd_dev = q->queuedata; @@ -2753,11 +2829,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, __le64 size; } __attribute__ ((packed)) size_buf = { 0 }; - ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, + (void) rbd_req_sync_exec; /* Avoid a warning */ + ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, "rbd", "get_size", (char *) &snapid, sizeof (snapid), (char *) &size_buf, sizeof (size_buf), NULL); - dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); + dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; @@ -2788,14 +2865,14 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) if (!reply_buf) return -ENOMEM; - ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, + ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, "rbd", "get_object_prefix", NULL, 0, r
[PATCH 11/12, v2] rbd: implement sync method with new code
Reimplement synchronous object method calls using the new request tracking code. Use the name rbd_obj_method_sync() Signed-off-by: Alex Elder --- drivers/block/rbd.c | 111 +++ 1 file changed, 94 insertions(+), 17 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 48650d1..5ad2ac2 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -1413,6 +1413,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, case CEPH_OSD_OP_WRITE: rbd_osd_write_callback(obj_request, op); break; + case CEPH_OSD_OP_CALL: case CEPH_OSD_OP_NOTIFY_ACK: case CEPH_OSD_OP_WATCH: rbd_osd_trivial_callback(obj_request, op); @@ -1903,6 +1904,81 @@ done: return ret; } +/* + * Synchronous osd object method call + */ +static int rbd_obj_method_sync(struct rbd_device *rbd_dev, +const char *object_name, +const char *class_name, +const char *method_name, +const char *outbound, +size_t outbound_size, +char *inbound, +size_t inbound_size, +u64 *version) +{ + struct rbd_obj_request *obj_request; + struct ceph_osd_client *osdc; + struct ceph_osd_req_op *op; + struct page **pages; + u32 page_count; + int ret; + + /* +* Method calls are ultimately read operations but they +* don't involve object data (so no offset or length). +* 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, 0, obj_req_pages); + if (!obj_request) + goto out; + + obj_request->pages = pages; + obj_request->page_count = page_count; + + op = rbd_osd_req_op_create(CEPH_OSD_OP_CALL, class_name, + method_name, outbound, outbound_size); + if (!op) + goto out; + obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, + obj_request, op); + rbd_osd_req_op_destroy(op); + if (!obj_request->osd_req) + goto out; + + osdc = &rbd_dev->rbd_client->client->osdc; + ret = rbd_obj_request_submit(osdc, obj_request); + if (ret) + goto out; + ret = rbd_obj_request_wait(obj_request); + if (ret) + goto out; + + ret = obj_request->result; + if (ret < 0) + goto out; + ret = ceph_copy_from_page_vector(pages, inbound, 0, + obj_request->xferred); + if (version) + *version = obj_request->version; +out: + if (obj_request) + rbd_obj_request_put(obj_request); + else + ceph_release_page_vector(pages, page_count); + + return ret; +} + static void rbd_request_fn(struct request_queue *q) { struct rbd_device *rbd_dev = q->queuedata; @@ -2753,11 +2829,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, __le64 size; } __attribute__ ((packed)) size_buf = { 0 }; - ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, + (void) rbd_req_sync_exec; /* Avoid a warning */ + ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, "rbd", "get_size", (char *) &snapid, sizeof (snapid), (char *) &size_buf, sizeof (size_buf), NULL); - dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); + dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; @@ -2788,14 +2865,14 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) if (!reply_buf) return -ENOMEM; - ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, + ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, "rbd", "get_object_prefix", NULL, 0, reply_buf, RBD_OBJ_PREFIX_LEN_MAX, NULL); - dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); + dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) goto out; - ret = 0;/* rbd_req_sync_exec()