ceph/osd_client: add support for CEPH_OSD_OP_GETXATTR
authorDavid Disseldorp <ddiss@suse.de>
Sun, 23 Aug 2015 22:32:00 +0000 (00:32 +0200)
committerDavid Disseldorp <ddiss@suse.de>
Mon, 24 Aug 2015 12:38:45 +0000 (14:38 +0200)
Allows for xattr retrieval. Response data buffer allocation is the
responsibility of the osd_req_op_xattr_init() caller.

Signed-off-by: David Disseldorp <ddiss@suse.de>
include/linux/ceph/osd_client.h
net/ceph/osd_client.c

index 8a1fb463f2cf78ed561061c14e0dd07bf165be46..8c88b3c3c19803147dfc6795ace190138c29a33e 100644 (file)
@@ -98,7 +98,8 @@ struct ceph_osd_req_op {
                        u32 value_len;
                        __u8 cmp_op;       /* CEPH_OSD_CMPXATTR_OP_* */
                        __u8 cmp_mode;     /* CEPH_OSD_CMPXATTR_MODE_* */
-                       struct ceph_osd_data osd_data;
+                       struct ceph_osd_data request_data;
+                       struct ceph_osd_data response_data;
                } xattr;
                struct {
                        const char *class_name;
@@ -351,6 +352,11 @@ extern void osd_req_op_notify_response_data_pages(struct ceph_osd_request *,
                                        struct page **pages, u64 length,
                                        u32 alignment, bool pages_from_pool,
                                        bool own_pages);
+extern void osd_req_op_xattr_response_data_pages(struct ceph_osd_request *,
+                                       unsigned int which,
+                                       struct page **pages, u64 length,
+                                       u32 alignment, bool pages_from_pool,
+                                       bool own_pages);
 extern void osd_req_op_notify_init(struct ceph_osd_request *osd_req,
                                   unsigned int which, u16 opcode, u64 cookie);
 extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req,
index 69d7109469608229c9efd071ca14abf8604a31d8..5bf651dff47accc4c404002454ad977e7068b7a0 100644 (file)
@@ -365,6 +365,18 @@ void osd_req_op_notify_request_data_pagelist(
 }
 EXPORT_SYMBOL(osd_req_op_notify_request_data_pagelist);
 
+void osd_req_op_xattr_response_data_pages(struct ceph_osd_request *osd_req,
+                       unsigned int which, struct page **pages, u64 length,
+                       u32 alignment, bool pages_from_pool, bool own_pages)
+{
+       struct ceph_osd_data *osd_data;
+
+       osd_data = osd_req_op_data(osd_req, which, xattr, response_data);
+       ceph_osd_data_pages_init(osd_data, pages, length, alignment,
+                               pages_from_pool, own_pages);
+}
+EXPORT_SYMBOL(osd_req_op_xattr_response_data_pages);
+
 static u64 ceph_osd_data_length(struct ceph_osd_data *osd_data)
 {
        switch (osd_data->type) {
@@ -431,7 +443,9 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
                break;
        case CEPH_OSD_OP_SETXATTR:
        case CEPH_OSD_OP_CMPXATTR:
-               ceph_osd_data_release(&op->xattr.osd_data);
+       case CEPH_OSD_OP_GETXATTR:
+               ceph_osd_data_release(&op->xattr.request_data);
+               ceph_osd_data_release(&op->xattr.response_data);
                break;
        case CEPH_OSD_OP_STAT:
                ceph_osd_data_release(&op->raw_data_in);
@@ -714,31 +728,44 @@ int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
 {
        struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which,
                                                      opcode, 0);
-       struct ceph_pagelist *pagelist;
+       struct ceph_pagelist *req_pagelist;
        size_t payload_len;
+       int ret;
 
-       BUG_ON(opcode != CEPH_OSD_OP_SETXATTR && opcode != CEPH_OSD_OP_CMPXATTR);
+       BUG_ON(opcode != CEPH_OSD_OP_SETXATTR
+               && opcode != CEPH_OSD_OP_CMPXATTR
+               && opcode != CEPH_OSD_OP_GETXATTR);
 
-       pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
-       if (!pagelist)
+       req_pagelist = kmalloc(sizeof(*req_pagelist), GFP_NOFS);
+       if (!req_pagelist)
                return -ENOMEM;
 
-       ceph_pagelist_init(pagelist);
+       ceph_pagelist_init(req_pagelist);
 
        payload_len = strlen(name);
        op->xattr.name_len = payload_len;
-       ceph_pagelist_append(pagelist, name, payload_len);
+       ret = ceph_pagelist_append(req_pagelist, name, payload_len);
+       if (ret) {
+               goto err_reqpl_free;
+       }
 
-       op->xattr.value_len = size;
-       ceph_pagelist_append(pagelist, value, size);
-       payload_len += size;
+       if (value) {
+               op->xattr.value_len = size;
+               ceph_pagelist_append(req_pagelist, value, size);
+               payload_len += size;
+       }
 
        op->xattr.cmp_op = cmp_op;
        op->xattr.cmp_mode = cmp_mode;
 
-       ceph_osd_data_pagelist_init(&op->xattr.osd_data, pagelist);
+       ceph_osd_data_pagelist_init(&op->xattr.request_data, req_pagelist);
        op->payload_len = payload_len;
+
        return 0;
+
+err_reqpl_free:
+       ceph_pagelist_release(req_pagelist);
+       return ret;
 }
 EXPORT_SYMBOL(osd_req_op_xattr_init);
 
@@ -931,13 +958,16 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                break;
        case CEPH_OSD_OP_SETXATTR:
        case CEPH_OSD_OP_CMPXATTR:
+       case CEPH_OSD_OP_GETXATTR:
                dst->xattr.name_len = cpu_to_le32(src->xattr.name_len);
                dst->xattr.value_len = cpu_to_le32(src->xattr.value_len);
                dst->xattr.cmp_op = src->xattr.cmp_op;
                dst->xattr.cmp_mode = src->xattr.cmp_mode;
-               osd_data = &src->xattr.osd_data;
+               osd_data = &src->xattr.request_data;
                ceph_osdc_msg_data_add(req->r_request, osd_data);
                request_data_len = osd_data->pagelist->length;
+               osd_data = &src->xattr.response_data;
+               ceph_osdc_msg_data_add(req->r_reply, osd_data);
                break;
        case CEPH_OSD_OP_CREATE:
        case CEPH_OSD_OP_DELETE: