aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-03-08 14:35:36 -0500
committerSage Weil <sage@inktank.com>2013-05-02 00:17:02 -0400
commit175face2ba31025b0dcd6da4e711fca7764287fa (patch)
tree8da146e3a923614defe47d78e0e262a1671b7f1a /net
parente766d7b55e10f93c7bab298135a4e90dcc46620d (diff)
libceph: let osd ops determine request data length
The length of outgoing data in an osd request is dependent on the osd ops that are embedded in that request. Each op is encoded into a request message using osd_req_encode_op(), so that should be used to determine the amount of outgoing data implied by the op as it is encoded. Have osd_req_encode_op() return the number of bytes of outgoing data implied by the op being encoded, and accumulate and use that in ceph_osdc_build_request(). As a result, ceph_osdc_build_request() no longer requires its "len" parameter, so get rid of it. Using the sum of the op lengths rather than the length provided is a valid change because: - The only callers of osd ceph_osdc_build_request() are rbd and the osd client (in ceph_osdc_new_request() on behalf of the file system). - When rbd calls it, the length provided is only non-zero for write requests, and in that case the single op has the same length value as what was passed here. - When called from ceph_osdc_new_request(), (it's not all that easy to see, but) the length passed is also always the same as the extent length encoded in its (single) write op if present. This resolves: http://tracker.ceph.com/issues/4406 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/osd_client.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 37d89614a61b..ce34faaa453f 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -222,10 +222,13 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
222} 222}
223EXPORT_SYMBOL(ceph_osdc_alloc_request); 223EXPORT_SYMBOL(ceph_osdc_alloc_request);
224 224
225static void osd_req_encode_op(struct ceph_osd_request *req, 225static u64 osd_req_encode_op(struct ceph_osd_request *req,
226 struct ceph_osd_op *dst, 226 struct ceph_osd_op *dst,
227 struct ceph_osd_req_op *src) 227 struct ceph_osd_req_op *src)
228{ 228{
229 u64 out_data_len = 0;
230 u64 tmp;
231
229 dst->op = cpu_to_le16(src->op); 232 dst->op = cpu_to_le16(src->op);
230 233
231 switch (src->op) { 234 switch (src->op) {
@@ -233,10 +236,10 @@ static void osd_req_encode_op(struct ceph_osd_request *req,
233 break; 236 break;
234 case CEPH_OSD_OP_READ: 237 case CEPH_OSD_OP_READ:
235 case CEPH_OSD_OP_WRITE: 238 case CEPH_OSD_OP_WRITE:
236 dst->extent.offset = 239 if (src->op == CEPH_OSD_OP_WRITE)
237 cpu_to_le64(src->extent.offset); 240 out_data_len = src->extent.length;
238 dst->extent.length = 241 dst->extent.offset = cpu_to_le64(src->extent.offset);
239 cpu_to_le64(src->extent.length); 242 dst->extent.length = cpu_to_le64(src->extent.length);
240 dst->extent.truncate_size = 243 dst->extent.truncate_size =
241 cpu_to_le64(src->extent.truncate_size); 244 cpu_to_le64(src->extent.truncate_size);
242 dst->extent.truncate_seq = 245 dst->extent.truncate_seq =
@@ -247,12 +250,14 @@ static void osd_req_encode_op(struct ceph_osd_request *req,
247 dst->cls.method_len = src->cls.method_len; 250 dst->cls.method_len = src->cls.method_len;
248 dst->cls.indata_len = cpu_to_le32(src->cls.indata_len); 251 dst->cls.indata_len = cpu_to_le32(src->cls.indata_len);
249 252
253 tmp = req->r_trail.length;
250 ceph_pagelist_append(&req->r_trail, src->cls.class_name, 254 ceph_pagelist_append(&req->r_trail, src->cls.class_name,
251 src->cls.class_len); 255 src->cls.class_len);
252 ceph_pagelist_append(&req->r_trail, src->cls.method_name, 256 ceph_pagelist_append(&req->r_trail, src->cls.method_name,
253 src->cls.method_len); 257 src->cls.method_len);
254 ceph_pagelist_append(&req->r_trail, src->cls.indata, 258 ceph_pagelist_append(&req->r_trail, src->cls.indata,
255 src->cls.indata_len); 259 src->cls.indata_len);
260 out_data_len = req->r_trail.length - tmp;
256 break; 261 break;
257 case CEPH_OSD_OP_STARTSYNC: 262 case CEPH_OSD_OP_STARTSYNC:
258 break; 263 break;
@@ -326,6 +331,8 @@ static void osd_req_encode_op(struct ceph_osd_request *req,
326 break; 331 break;
327 } 332 }
328 dst->payload_len = cpu_to_le32(src->payload_len); 333 dst->payload_len = cpu_to_le32(src->payload_len);
334
335 return out_data_len;
329} 336}
330 337
331/* 338/*
@@ -333,7 +340,7 @@ static void osd_req_encode_op(struct ceph_osd_request *req,
333 * 340 *
334 */ 341 */
335void ceph_osdc_build_request(struct ceph_osd_request *req, 342void ceph_osdc_build_request(struct ceph_osd_request *req,
336 u64 off, u64 len, unsigned int num_ops, 343 u64 off, unsigned int num_ops,
337 struct ceph_osd_req_op *src_ops, 344 struct ceph_osd_req_op *src_ops,
338 struct ceph_snap_context *snapc, u64 snap_id, 345 struct ceph_snap_context *snapc, u64 snap_id,
339 struct timespec *mtime) 346 struct timespec *mtime)
@@ -385,12 +392,13 @@ void ceph_osdc_build_request(struct ceph_osd_request *req,
385 dout("oid '%.*s' len %d\n", req->r_oid_len, req->r_oid, req->r_oid_len); 392 dout("oid '%.*s' len %d\n", req->r_oid_len, req->r_oid, req->r_oid_len);
386 p += req->r_oid_len; 393 p += req->r_oid_len;
387 394
388 /* ops */ 395 /* ops--can imply data */
389 ceph_encode_16(&p, num_ops); 396 ceph_encode_16(&p, num_ops);
390 src_op = src_ops; 397 src_op = src_ops;
391 req->r_request_ops = p; 398 req->r_request_ops = p;
399 data_len = 0;
392 for (i = 0; i < num_ops; i++, src_op++) { 400 for (i = 0; i < num_ops; i++, src_op++) {
393 osd_req_encode_op(req, p, src_op); 401 data_len += osd_req_encode_op(req, p, src_op);
394 p += sizeof(struct ceph_osd_op); 402 p += sizeof(struct ceph_osd_op);
395 } 403 }
396 404
@@ -407,11 +415,9 @@ void ceph_osdc_build_request(struct ceph_osd_request *req,
407 req->r_request_attempts = p; 415 req->r_request_attempts = p;
408 p += 4; 416 p += 4;
409 417
410 data_len = req->r_trail.length; 418 /* data */
411 if (flags & CEPH_OSD_FLAG_WRITE) { 419 if (flags & CEPH_OSD_FLAG_WRITE)
412 req->r_request->hdr.data_off = cpu_to_le16(off); 420 req->r_request->hdr.data_off = cpu_to_le16(off);
413 data_len += len;
414 }
415 req->r_request->hdr.data_len = cpu_to_le32(data_len); 421 req->r_request->hdr.data_len = cpu_to_le32(data_len);
416 422
417 BUG_ON(p > msg->front.iov_base + msg->front.iov_len); 423 BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
@@ -477,13 +483,12 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
477 ceph_osdc_put_request(req); 483 ceph_osdc_put_request(req);
478 return ERR_PTR(r); 484 return ERR_PTR(r);
479 } 485 }
480
481 req->r_file_layout = *layout; /* keep a copy */ 486 req->r_file_layout = *layout; /* keep a copy */
482 487
483 snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno); 488 snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno);
484 req->r_oid_len = strlen(req->r_oid); 489 req->r_oid_len = strlen(req->r_oid);
485 490
486 ceph_osdc_build_request(req, off, *plen, num_op, ops, 491 ceph_osdc_build_request(req, off, num_op, ops,
487 snapc, vino.snap, mtime); 492 snapc, vino.snap, mtime);
488 493
489 return req; 494 return req;