From 21fc535ea7284ad0db5d3430f81c08199e854988 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 22 Mar 2014 15:39:26 -0700 Subject: [PATCH] osd: trim copy-get backend read to object size We are passing a big number to the backend to read and it is trimming it to the stripe boundary, and then setting the cursor at a slightly smaller offset bound by oi.size. This is invalid, and will trigger an assert in the _write_copy_chunk code: 0> 2014-03-21 15:12:23.761509 7f8dd2324700 -1 osd/ReplicatedPG.cc: In function 'void ReplicatedPG::_write_copy_chunk(ReplicatedPG::CopyOpRef, PGBackend::PGTransaction*)' thread 7f8dd2324700 time 2014-03-21 15:12:23.758866 osd/ReplicatedPG.cc: 5554: FAILED assert(cop->data.length() + cop->temp_cursor.data_offset == cop->cursor.data_offset) To fix this, trim the buffer to the correct length in the completion context. Fixes: #7823 Signed-off-by: Sage Weil --- src/osd/ReplicatedPG.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index faf00a720acac..4004432891e3c 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -5202,9 +5202,15 @@ struct C_CopyFrom_AsyncReadCb : public Context { OSDOp *osd_op; object_copy_data_t reply_obj; bool classic; + size_t len; C_CopyFrom_AsyncReadCb(OSDOp *osd_op, bool classic) : - osd_op(osd_op), classic(classic) {} + osd_op(osd_op), classic(classic), len(0) {} void finish(int r) { + assert(len > 0); + assert(len <= reply_obj.data.length()); + bufferlist bl; + bl.substr_of(reply_obj.data, 0, len); + reply_obj.data.swap(bl); if (classic) { reply_obj.encode_classic(osd_op->outdata); } else { @@ -5282,6 +5288,7 @@ int ReplicatedPG::fill_in_copy_get( make_pair(cursor.data_offset, left), make_pair(&bl, cb))); result = MIN(oi.size - cursor.data_offset, (uint64_t)left); + cb->len = result; } else { result = pgbackend->objects_read_sync( oi.soid, cursor.data_offset, left, &bl); -- 2.39.5