libceph: add helper that duplicates last extent operation
authorYan, Zheng <zyan@redhat.com>
Thu, 7 Jan 2016 09:32:54 +0000 (17:32 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 25 Mar 2016 17:51:43 +0000 (18:51 +0100)
This helper duplicates last extent operation in OSD request, then
adjusts the new extent operation's offset and length. The helper
is for scatterd page writeback, which adds nonconsecutive dirty
pages to single OSD request.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
include/linux/ceph/osd_client.h
net/ceph/osd_client.c

index aada6a1383a4ccfe25f25c3b2916ff9751a496ff..4343df80671019a01e7a0b7aeec89f191670e6f0 100644 (file)
@@ -266,6 +266,8 @@ extern void osd_req_op_extent_init(struct ceph_osd_request *osd_req,
                                        u64 truncate_size, u32 truncate_seq);
 extern void osd_req_op_extent_update(struct ceph_osd_request *osd_req,
                                        unsigned int which, u64 length);
+extern void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req,
+                                      unsigned int which, u64 offset_inc);
 
 extern struct ceph_osd_data *osd_req_op_extent_osd_data(
                                        struct ceph_osd_request *osd_req,
index ccd4e031fa3f20ea9200395f16b620e4357420a8..32355d9d0103a827a82f3bfe27493d9a2b47b339 100644 (file)
@@ -534,6 +534,28 @@ void osd_req_op_extent_update(struct ceph_osd_request *osd_req,
 }
 EXPORT_SYMBOL(osd_req_op_extent_update);
 
+void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req,
+                               unsigned int which, u64 offset_inc)
+{
+       struct ceph_osd_req_op *op, *prev_op;
+
+       BUG_ON(which + 1 >= osd_req->r_num_ops);
+
+       prev_op = &osd_req->r_ops[which];
+       op = _osd_req_op_init(osd_req, which + 1, prev_op->op, prev_op->flags);
+       /* dup previous one */
+       op->indata_len = prev_op->indata_len;
+       op->outdata_len = prev_op->outdata_len;
+       op->extent = prev_op->extent;
+       /* adjust offset */
+       op->extent.offset += offset_inc;
+       op->extent.length -= offset_inc;
+
+       if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL)
+               op->indata_len -= offset_inc;
+}
+EXPORT_SYMBOL(osd_req_op_extent_dup_last);
+
 void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
                        u16 opcode, const char *class, const char *method)
 {