From: Jeff Layton Date: Thu, 17 Feb 2022 12:41:31 +0000 (-0500) Subject: osd: allow sparse reads with a non-zero truncate-seq X-Git-Tag: v18.0.0~1239^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=58f3e8bb98b966935898ef1c3eed61be7768d513;p=ceph.git osd: allow sparse reads with a non-zero truncate-seq do_read() just uses the truncate_seq to tell how to cap the length of the read. I see no reason that sparse reads should do anything differently. Change do_sparse_read() to cap the requested length at the truncate_size if the truncate_seq in the request is newer than the one in the object. Fixes: https://tracker.ceph.com/issues/54280 Signed-off-by: Jeff Layton --- diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index fb3f0adb5eef..ee033ac362af 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -5846,22 +5846,26 @@ int PrimaryLogPG::do_sparse_read(OpContext *ctx, OSDOp& osd_op) { auto& op = osd_op.op; auto& oi = ctx->new_obs.oi; auto& soid = oi.soid; + uint64_t size = oi.size; + uint64_t offset = op.extent.offset; + uint64_t length = op.extent.length; - if (op.extent.truncate_seq) { - dout(0) << "sparse_read does not support truncation sequence " << dendl; - return -EINVAL; + // are we beyond truncate_size? + if ((oi.truncate_seq < op.extent.truncate_seq) && + (op.extent.offset + op.extent.length > op.extent.truncate_size) && + (size > op.extent.truncate_size)) { + size = op.extent.truncate_size; + } + + if (offset > size) { + length = 0; + } else if (offset + length > size) { + length = size - offset; } ++ctx->num_read; if (pool.info.is_erasure()) { // translate sparse read to a normal one if not supported - uint64_t offset = op.extent.offset; - uint64_t length = op.extent.length; - if (offset > oi.size) { - length = 0; - } else if (offset + length > oi.size) { - length = oi.size - offset; - } if (length > 0) { ctx->pending_async_reads.push_back( @@ -5885,7 +5889,7 @@ int PrimaryLogPG::do_sparse_read(OpContext *ctx, OSDOp& osd_op) { map m; int r = osd->store->fiemap(ch, ghobject_t(soid, ghobject_t::NO_GEN, info.pgid.shard), - op.extent.offset, op.extent.length, m); + offset, length, m); if (r < 0) { return r; }