From 7453841d397893c0733165e2559e0919d5ac9dda 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, bsc#1177090
Patch-mainline: Not yet, SES 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.]
Acked-by: Luis Henriques <lhenriques@suse.com>
[luis: updated get_num_data_items() introduced by commit 0d9c1ab3be4c
("libceph: preallocate message data items")]
[luis: rebased atop 26f887e0a3c4 ("libceph, rbd, ceph: move
ceph_osdc_alloc_messages() calls")]
---
include/linux/ceph/rados.h | 3 +++
net/ceph/osd_client.c | 18 +++++++++++++-----
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/include/linux/ceph/rados.h b/include/linux/ceph/rados.h
index 88ed3c5c04c5..9e523023eb92 100644
--- a/include/linux/ceph/rados.h
+++ b/include/linux/ceph/rados.h
@@ -273,6 +273,9 @@ extern const char *ceph_osd_state_name(int s);
/* 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") \
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 99f35b7f765d..a3453b80299b 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -378,6 +378,7 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
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:
@@ -699,6 +700,7 @@ static void get_num_data_items(struct ceph_osd_request *req,
case CEPH_OSD_OP_CMPXATTR:
case CEPH_OSD_OP_NOTIFY_ACK:
case CEPH_OSD_OP_COPY_FROM2:
+ case CEPH_OSD_OP_CMPEXT:
*num_request_data_items += 1;
break;
@@ -780,13 +782,14 @@ void osd_req_op_extent_init(struct ceph_osd_request *osd_req,
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;
@@ -808,7 +811,8 @@ void osd_req_op_extent_update(struct ceph_osd_request *osd_req,
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);
@@ -830,7 +834,8 @@ void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req,
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);
@@ -989,6 +994,7 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst,
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 =
@@ -1080,7 +1086,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
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);
@@ -1952,6 +1959,7 @@ static void setup_request_data(struct ceph_osd_request *req)
/* 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(request_msg,
&op->extent.osd_data);
--
2.26.2