From 7240fdf187fe0d007ccceaad76015fbd23b432bc Mon Sep 17 00:00:00 2001
From: Mike Christie <michaelc@cs.wisc.edu>
Date: Wed, 29 Jul 2015 04:23:42 -0500
Subject: [PATCH] libceph: add support for CMPEXT compare extent requests
References: fate#318836
Patch-mainline: Not yet, SES2 clustered LIO/RBD
This adds support for the CMPEXT request. The request will compare
extent.length bytes and compare them to extent.length bytes at
extent.offset on disk. If there is a miscompare the osd will return
-MAX_ERRNO - offset_of_miscompare.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Acked-by: David Disseldorp <ddiss@suse.de>
[ddiss@suse.de: reworked to use new API, which isn't bidirectional.]
---
---
include/linux/ceph/rados.h | 3 +++
net/ceph/osd_client.c | 17 ++++++++++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
--- a/include/linux/ceph/rados.h
+++ b/include/linux/ceph/rados.h
@@ -269,6 +269,9 @@ extern const char *ceph_osd_state_name(i
/* hints */ \
f(SETALLOCHINT, __CEPH_OSD_OP(WR, DATA, 35), "set-alloc-hint") \
\
+ /* ESX/SCSI */ \
+ f(CMPEXT, __CEPH_OSD_OP(RD, DATA, 32), "cmpext") \
+ \
/** multi **/ \
f(CLONERANGE, __CEPH_OSD_OP(WR, MULTI, 1), "clonerange") \
f(ASSERT_SRC_VERSION, __CEPH_OSD_OP(RD, MULTI, 2), "assert-src-version") \
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -342,6 +342,7 @@ static void osd_req_op_data_release(stru
case CEPH_OSD_OP_READ:
case CEPH_OSD_OP_WRITE:
case CEPH_OSD_OP_WRITEFULL:
+ case CEPH_OSD_OP_CMPEXT:
ceph_osd_data_release(&op->extent.osd_data);
break;
case CEPH_OSD_OP_CALL:
@@ -676,13 +677,14 @@ void osd_req_op_extent_init(struct ceph_
BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
opcode != CEPH_OSD_OP_WRITEFULL && opcode != CEPH_OSD_OP_ZERO &&
- opcode != CEPH_OSD_OP_TRUNCATE);
+ opcode != CEPH_OSD_OP_TRUNCATE && opcode != CEPH_OSD_OP_CMPEXT);
op->extent.offset = offset;
op->extent.length = length;
op->extent.truncate_size = truncate_size;
op->extent.truncate_seq = truncate_seq;
- if (opcode == CEPH_OSD_OP_WRITE || opcode == CEPH_OSD_OP_WRITEFULL)
+ if (opcode == CEPH_OSD_OP_WRITE || opcode == CEPH_OSD_OP_WRITEFULL
+ || opcode == CEPH_OSD_OP_CMPEXT)
payload_len += length;
op->indata_len = payload_len;
@@ -704,7 +706,8 @@ void osd_req_op_extent_update(struct cep
BUG_ON(length > previous);
op->extent.length = length;
- if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL)
+ if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL
+ || op->op == CEPH_OSD_OP_CMPEXT)
op->indata_len -= previous - length;
}
EXPORT_SYMBOL(osd_req_op_extent_update);
@@ -726,7 +729,8 @@ void osd_req_op_extent_dup_last(struct c
op->extent.offset += offset_inc;
op->extent.length -= offset_inc;
- if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL)
+ if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL
+ || op->op == CEPH_OSD_OP_CMPEXT)
op->indata_len -= offset_inc;
}
EXPORT_SYMBOL(osd_req_op_extent_dup_last);
@@ -877,6 +881,7 @@ static u32 osd_req_encode_op(struct ceph
case CEPH_OSD_OP_WRITEFULL:
case CEPH_OSD_OP_ZERO:
case CEPH_OSD_OP_TRUNCATE:
+ case CEPH_OSD_OP_CMPEXT:
dst->extent.offset = cpu_to_le64(src->extent.offset);
dst->extent.length = cpu_to_le64(src->extent.length);
dst->extent.truncate_size =
@@ -960,7 +965,8 @@ struct ceph_osd_request *ceph_osdc_new_r
BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
opcode != CEPH_OSD_OP_ZERO && opcode != CEPH_OSD_OP_TRUNCATE &&
- opcode != CEPH_OSD_OP_CREATE && opcode != CEPH_OSD_OP_DELETE);
+ opcode != CEPH_OSD_OP_CREATE && opcode != CEPH_OSD_OP_DELETE &&
+ opcode != CEPH_OSD_OP_CMPEXT);
req = ceph_osdc_alloc_request(osdc, snapc, num_ops, use_mempool,
GFP_NOFS);
@@ -1802,6 +1808,7 @@ static void setup_request_data(struct ce
/* request */
case CEPH_OSD_OP_WRITE:
case CEPH_OSD_OP_WRITEFULL:
+ case CEPH_OSD_OP_CMPEXT:
WARN_ON(op->indata_len != op->extent.length);
ceph_osdc_msg_data_add(msg, &op->extent.osd_data);
break;