From ed123390035ceef82490d4a4d45ada878fb7423f Mon Sep 17 00:00:00 2001
From: Mike Christie <michaelc@cs.wisc.edu>
Date: Wed, 29 Jul 2015 04:23:47 -0500
Subject: [PATCH] rbd: add support for writesame requests
References: fate#318836
Patch-mainline: Not yet, SES2 clustered LIO/RBD
This adds support for ceph writesame requests.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Acked-by: David Disseldorp <ddiss@suse.de>
---
drivers/block/rbd.c | 59 ++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 8 deletions(-)
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -224,6 +224,7 @@ enum obj_operation_type {
OBJ_OP_READ,
OBJ_OP_DISCARD,
OBJ_OP_CMP_AND_WRITE,
+ OBJ_OP_WRITESAME,
};
enum obj_req_flags {
@@ -298,6 +299,7 @@ enum img_req_flags {
IMG_REQ_LAYERED, /* ENOENT handling: normal = 0, layered = 1 */
IMG_REQ_DISCARD, /* discard: normal = 0, discard request = 1 */
IMG_REQ_CMP_AND_WRITE, /* normal = 0, compare and write request = 1 */
+ IMG_REQ_WRITESAME, /* normal = 0, write same = 1 */
};
struct rbd_img_request {
@@ -892,6 +894,7 @@ static int obj_num_ops(enum obj_operatio
{
switch (op_type) {
case OBJ_OP_WRITE:
+ case OBJ_OP_WRITESAME:
return 2;
case OBJ_OP_CMP_AND_WRITE:
return 3;
@@ -1715,6 +1718,17 @@ static bool img_request_write_test(struc
return test_bit(IMG_REQ_WRITE, &img_request->flags) != 0;
}
+static void img_request_writesame_set(struct rbd_img_request *img_request)
+{
+ set_bit(IMG_REQ_WRITESAME, &img_request->flags);
+ smp_mb();
+}
+
+static bool img_request_writesame_test(struct rbd_img_request *img_request)
+{
+ smp_mb();
+ return test_bit(IMG_REQ_WRITESAME, &img_request->flags) != 0;
+}
/*
* Set the discard flag when the img_request is an discard request
*/
@@ -1781,6 +1795,7 @@ static bool img_request_cmp_and_write_te
static bool img_request_is_write_type_test(struct rbd_img_request *img_request)
{
return img_request_write_test(img_request) ||
+ img_request_writesame_test(img_request) ||
img_request_discard_test(img_request) ||
img_request_cmp_and_write_test(img_request);
}
@@ -1794,6 +1809,8 @@ rbd_img_request_op_type(struct rbd_img_r
return OBJ_OP_DISCARD;
else if (img_request_cmp_and_write_test(img_request))
return OBJ_OP_CMP_AND_WRITE;
+ else if (img_request_writesame_test(img_request))
+ return OBJ_OP_WRITESAME;
else
return OBJ_OP_READ;
}
@@ -1976,7 +1993,8 @@ static void rbd_osd_req_callback(struct
break;
case CEPH_OSD_OP_SETALLOCHINT:
if (osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE ||
- osd_req->r_ops[1].op == CEPH_OSD_OP_WRITEFULL)
+ osd_req->r_ops[1].op == CEPH_OSD_OP_WRITEFULL ||
+ osd_req->r_ops[1].op == CEPH_OSD_OP_WRITESAME)
rbd_osd_write_callback(obj_request);
else if (osd_req->r_ops[1].op == CEPH_OSD_OP_CMPEXT)
rbd_osd_cmpext_callback(obj_request, osd_req);
@@ -1985,6 +2003,7 @@ static void rbd_osd_req_callback(struct
break;
case CEPH_OSD_OP_WRITE:
case CEPH_OSD_OP_WRITEFULL:
+ case CEPH_OSD_OP_WRITESAME:
rbd_osd_write_callback(obj_request);
break;
case CEPH_OSD_OP_CMPEXT:
@@ -2084,7 +2103,8 @@ static struct ceph_osd_request *rbd_osd_
if (obj_request_img_data_test(obj_request) &&
(op_type == OBJ_OP_DISCARD || op_type == OBJ_OP_WRITE ||
- op_type == OBJ_OP_CMP_AND_WRITE)) {
+ op_type == OBJ_OP_CMP_AND_WRITE ||
+ op_type == OBJ_OP_WRITESAME)) {
struct rbd_img_request *img_request = obj_request->img_request;
if (op_type == OBJ_OP_WRITE) {
rbd_assert(img_request_write_test(img_request));
@@ -2092,6 +2112,8 @@ static struct ceph_osd_request *rbd_osd_
rbd_assert(img_request_discard_test(img_request));
} else if (op_type == OBJ_OP_CMP_AND_WRITE) {
rbd_assert(img_request_cmp_and_write_test(img_request));
+ } else if (op_type == OBJ_OP_WRITESAME) {
+ rbd_assert(img_request_writesame_test(img_request));
}
snapc = img_request->snapc;
}
@@ -2100,7 +2122,7 @@ static struct ceph_osd_request *rbd_osd_
return __rbd_osd_req_create(rbd_dev, snapc, num_ops,
(op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD ||
- op_type == OBJ_OP_CMP_AND_WRITE) ?
+ op_type == OBJ_OP_CMP_AND_WRITE || op_type == OBJ_OP_WRITESAME) ?
CEPH_OSD_FLAG_WRITE : CEPH_OSD_FLAG_READ, obj_request);
}
@@ -2281,6 +2303,9 @@ static struct rbd_img_request *rbd_img_r
} else if (op_type == OBJ_OP_WRITE) {
img_request_write_set(img_request);
img_request->snapc = snapc;
+ } else if (op_type == OBJ_OP_WRITESAME) {
+ img_request_writesame_set(img_request);
+ img_request->snapc = snapc;
} else if (op_type == OBJ_OP_CMP_AND_WRITE) {
img_request_cmp_and_write_set(img_request);
img_request->snapc = snapc;
@@ -2497,12 +2522,21 @@ static void rbd_img_obj_request_fill(str
osd_req_op_alloc_hint_init(osd_request, num_ops,
object_size, object_size);
num_ops++;
+ } else if (op_type == OBJ_OP_WRITESAME) {
+ opcode = CEPH_OSD_OP_WRITESAME;
+ osd_req_op_alloc_hint_init(osd_request, num_ops,
+ object_size, object_size);
+ num_ops++;
} else {
opcode = CEPH_OSD_OP_READ;
}
if (opcode == CEPH_OSD_OP_DELETE)
osd_req_op_init(osd_request, num_ops, opcode, 0);
+ else if (opcode == CEPH_OSD_OP_WRITESAME)
+ osd_req_op_writesame_init(osd_request, num_ops, opcode,
+ offset, length, min_t(u64, length,
+ obj_request->sg->length));
else
osd_req_op_extent_init(osd_request, num_ops, opcode,
offset, length, 0, 0);
@@ -2514,13 +2548,22 @@ static void rbd_img_obj_request_fill(str
osd_req_op_extent_osd_data_pages(osd_request, num_ops,
obj_request->pages, length,
offset & ~PAGE_MASK, false, false);
- else if (obj_request->type == OBJ_REQUEST_SG)
- osd_req_op_extent_osd_data_sg(osd_request, num_ops,
- obj_request->sg,
- obj_request->init_sg_offset, length);
+ else if (obj_request->type == OBJ_REQUEST_SG) {
+ if (op_type == OBJ_OP_WRITESAME)
+ osd_req_op_writesame_osd_data_sg(osd_request, num_ops,
+ obj_request->sg,
+ obj_request->init_sg_offset,
+ min_t(u64, length,
+ obj_request->sg->length));
+ else
+ osd_req_op_extent_osd_data_sg(osd_request, num_ops,
+ obj_request->sg,
+ obj_request->init_sg_offset,
+ length);
+ }
/* Discards are also writes */
- if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
+ if (img_request_is_write_type_test(img_request))
rbd_osd_req_format_write(obj_request);
else
rbd_osd_req_format_read(obj_request);