libceph: add ceph_osdc_call() single-page helper
authorDouglas Fuller <dfuller@redhat.com>
Wed, 17 Jun 2015 18:49:45 +0000 (14:49 -0400)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 24 Aug 2016 21:49:15 +0000 (23:49 +0200)
Add a convenience function to osd_client to send Ceph OSD
'class' ops. The interface assumes that the request and
reply data each consist of single pages.

Signed-off-by: Douglas Fuller <dfuller@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Mike Christie <mchristi@redhat.com>
Reviewed-by: Alex Elder <elder@linaro.org>
include/linux/ceph/osd_client.h
net/ceph/osd_client.c

index 19821a1..96337b1 100644 (file)
@@ -397,6 +397,14 @@ extern void ceph_osdc_sync(struct ceph_osd_client *osdc);
 extern void ceph_osdc_flush_notifies(struct ceph_osd_client *osdc);
 void ceph_osdc_maybe_request_map(struct ceph_osd_client *osdc);
 
+int ceph_osdc_call(struct ceph_osd_client *osdc,
+                  struct ceph_object_id *oid,
+                  struct ceph_object_locator *oloc,
+                  const char *class, const char *method,
+                  unsigned int flags,
+                  struct page *req_page, size_t req_len,
+                  struct page *resp_page, size_t *resp_len);
+
 extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                               struct ceph_vino vino,
                               struct ceph_file_layout *layout,
index dd51ec8..fbc6b70 100644 (file)
@@ -4026,6 +4026,57 @@ void ceph_osdc_maybe_request_map(struct ceph_osd_client *osdc)
 }
 EXPORT_SYMBOL(ceph_osdc_maybe_request_map);
 
+/*
+ * Execute an OSD class method on an object.
+ *
+ * @flags: CEPH_OSD_FLAG_*
+ * @resp_len: out param for reply length
+ */
+int ceph_osdc_call(struct ceph_osd_client *osdc,
+                  struct ceph_object_id *oid,
+                  struct ceph_object_locator *oloc,
+                  const char *class, const char *method,
+                  unsigned int flags,
+                  struct page *req_page, size_t req_len,
+                  struct page *resp_page, size_t *resp_len)
+{
+       struct ceph_osd_request *req;
+       int ret;
+
+       req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_NOIO);
+       if (!req)
+               return -ENOMEM;
+
+       ceph_oid_copy(&req->r_base_oid, oid);
+       ceph_oloc_copy(&req->r_base_oloc, oloc);
+       req->r_flags = flags;
+
+       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
+       if (ret)
+               goto out_put_req;
+
+       osd_req_op_cls_init(req, 0, CEPH_OSD_OP_CALL, class, method);
+       if (req_page)
+               osd_req_op_cls_request_data_pages(req, 0, &req_page, req_len,
+                                                 0, false, false);
+       if (resp_page)
+               osd_req_op_cls_response_data_pages(req, 0, &resp_page,
+                                                  PAGE_SIZE, 0, false, false);
+
+       ceph_osdc_start_request(osdc, req, false);
+       ret = ceph_osdc_wait_request(osdc, req);
+       if (ret >= 0) {
+               ret = req->r_ops[0].rval;
+               if (resp_page)
+                       *resp_len = req->r_ops[0].outdata_len;
+       }
+
+out_put_req:
+       ceph_osdc_put_request(req);
+       return ret;
+}
+EXPORT_SYMBOL(ceph_osdc_call);
+
 /*
  * init, shutdown
  */