From: Kefu Chai Date: Thu, 27 Aug 2015 14:57:49 +0000 (+0800) Subject: osd: translate sparse_read to read for ecpool X-Git-Tag: v0.94.6~103^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=318049911445a3cc257db2b3beb3ab53e6f1d64e;p=ceph.git osd: translate sparse_read to read for ecpool Fixes: #12012 Signed-off-by: Kefu Chai (cherry picked from commit 700d42ef1c82f5602249b96690ae881c1d259d54) --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 6b22c3a845a6..8dd6f38e15a0 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -3277,6 +3277,23 @@ struct FillInExtent : public Context { } }; +struct ToSparseReadResult : public Context { + bufferlist& data_bl; + ceph_le64& len; + ToSparseReadResult(bufferlist& bl, ceph_le64& len): + data_bl(bl), len(len) {} + void finish(int r) { + if (r < 0) return; + len = r; + bufferlist outdata; + map extents; + extents.insert(make_pair(0, len)); + ::encode(extents, outdata); + ::encode_destructively(data_bl, outdata); + data_bl.swap(outdata); + } +}; + template static string list_keys(const map& m) { string s; @@ -3501,17 +3518,21 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector& ops) /* map extents */ case CEPH_OSD_OP_SPARSE_READ: tracepoint(osd, do_osd_op_pre_sparse_read, soid.oid.name.c_str(), soid.snap.val, oi.size, oi.truncate_seq, op.extent.offset, op.extent.length, op.extent.truncate_size, op.extent.truncate_seq); - if (pool.info.require_rollback()) { - result = -EOPNOTSUPP; + if (op.extent.truncate_seq) { + dout(0) << "sparse_read does not support truncation sequence " << dendl; + result = -EINVAL; break; } ++ctx->num_read; - { - if (op.extent.truncate_seq) { - dout(0) << "sparse_read does not support truncation sequence " << dendl; - result = -EINVAL; - break; - } + if (pool.info.require_rollback()) { + // translate sparse read to a normal one if not supported + ctx->pending_async_reads.push_back( + make_pair( + boost::make_tuple(op.extent.offset, op.extent.length, op.flags), + make_pair(&osd_op.outdata, new ToSparseReadResult(osd_op.outdata, + op.extent.length)))); + dout(10) << " async_read (was sparse_read) noted for " << soid << dendl; + } else { // read into a buffer bufferlist bl; int total_read = 0; @@ -3576,11 +3597,10 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector& ops) ::encode(m, osd_op.outdata); ::encode(data_bl, osd_op.outdata); - ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(op.extent.length, 10); - ctx->delta_stats.num_rd++; - dout(10) << " sparse_read got " << total_read << " bytes from object " << soid << dendl; } + ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(op.extent.length, 10); + ctx->delta_stats.num_rd++; break; case CEPH_OSD_OP_CALL: