libceph: add SETXATTR/CMPXATTR osd operations support
authorYan, Zheng <zyan@redhat.com>
Wed, 12 Nov 2014 06:00:43 +0000 (14:00 +0800)
committerIlya Dryomov <idryomov@redhat.com>
Wed, 17 Dec 2014 17:09:51 +0000 (20:09 +0300)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Reviewed-by: Ilya Dryomov <idryomov@redhat.com>
include/linux/ceph/osd_client.h
net/ceph/osd_client.c

index 03aeb27..bcf9c21 100644 (file)
@@ -86,6 +86,13 @@ struct ceph_osd_req_op {
                        u32 truncate_seq;
                        struct ceph_osd_data osd_data;
                } extent;
+               struct {
+                       __le32 name_len;
+                       __le32 value_len;
+                       __u8 cmp_op;       /* CEPH_OSD_CMPXATTR_OP_* */
+                       __u8 cmp_mode;     /* CEPH_OSD_CMPXATTR_MODE_* */
+                       struct ceph_osd_data osd_data;
+               } xattr;
                struct {
                        const char *class_name;
                        const char *method_name;
@@ -295,6 +302,9 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *,
 extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req,
                                        unsigned int which, u16 opcode,
                                        const char *class, const char *method);
+extern int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
+                                u16 opcode, const char *name, const void *value,
+                                size_t size, u8 cmp_op, u8 cmp_mode);
 extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req,
                                        unsigned int which, u16 opcode,
                                        u64 cookie, u64 version, int flag);
index 1f6c405..2b0555b 100644 (file)
@@ -292,6 +292,10 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
                ceph_osd_data_release(&op->cls.request_data);
                ceph_osd_data_release(&op->cls.response_data);
                break;
+       case CEPH_OSD_OP_SETXATTR:
+       case CEPH_OSD_OP_CMPXATTR:
+               ceph_osd_data_release(&op->xattr.osd_data);
+               break;
        default:
                break;
        }
@@ -545,6 +549,39 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
 }
 EXPORT_SYMBOL(osd_req_op_cls_init);
 
+int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
+                         u16 opcode, const char *name, const void *value,
+                         size_t size, u8 cmp_op, u8 cmp_mode)
+{
+       struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which, opcode);
+       struct ceph_pagelist *pagelist;
+       size_t payload_len;
+
+       BUG_ON(opcode != CEPH_OSD_OP_SETXATTR && opcode != CEPH_OSD_OP_CMPXATTR);
+
+       pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+       if (!pagelist)
+               return -ENOMEM;
+
+       ceph_pagelist_init(pagelist);
+
+       payload_len = strlen(name);
+       op->xattr.name_len = payload_len;
+       ceph_pagelist_append(pagelist, name, payload_len);
+
+       op->xattr.value_len = size;
+       ceph_pagelist_append(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);
+       op->payload_len = payload_len;
+       return 0;
+}
+EXPORT_SYMBOL(osd_req_op_xattr_init);
+
 void osd_req_op_watch_init(struct ceph_osd_request *osd_req,
                                unsigned int which, u16 opcode,
                                u64 cookie, u64 version, int flag)
@@ -676,6 +713,16 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                dst->alloc_hint.expected_write_size =
                    cpu_to_le64(src->alloc_hint.expected_write_size);
                break;
+       case CEPH_OSD_OP_SETXATTR:
+       case CEPH_OSD_OP_CMPXATTR:
+               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;
+               ceph_osdc_msg_data_add(req->r_request, osd_data);
+               request_data_len = osd_data->pagelist->length;
+               break;
        default:
                pr_err("unsupported osd opcode %s\n",
                        ceph_osd_op_name(src->op));