From 5be9c3754dda4f9b7641a523016c65f0fb954363 Mon Sep 17 00:00:00 2001 From: chunmei-liu Date: Thu, 9 Jun 2022 00:44:01 -0700 Subject: [PATCH] crimson/osd: check truncate size in sparse_read Signed-off-by: chunmei-liu --- src/crimson/osd/pg_backend.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 829b8ea07c93..5460e8bfd712 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -239,11 +239,28 @@ PGBackend::sparse_read(const ObjectState& os, OSDOp& osd_op, } const auto& op = osd_op.op; + /* clients (particularly cephfs) may send truncate operations out of order + * w.r.t. reads. op.extent.truncate_seq and op.extent.truncate_size allow + * the OSD to determine whether the client submitted read needs to be + * adjusted to compensate for a truncate the OSD hasn't seen yet. + */ + uint64_t adjusted_size = os.oi.size; + const uint64_t offset = op.extent.offset; + uint64_t adjusted_length = op.extent.length; + if ((os.oi.truncate_seq < op.extent.truncate_seq) && + (op.extent.offset + op.extent.length > op.extent.truncate_size) && + (adjusted_size > op.extent.truncate_size)) { + adjusted_size = op.extent.truncate_size; + } + if (offset > adjusted_size) { + adjusted_length = 0; + } else if (offset + adjusted_length > adjusted_size) { + adjusted_length = adjusted_size - offset; + } logger().trace("sparse_read: {} {}~{}", os.oi.soid, op.extent.offset, op.extent.length); return interruptor::make_interruptible(store->fiemap(coll, ghobject_t{os.oi.soid}, - op.extent.offset, - op.extent.length)).safe_then_interruptible( + offset, adjusted_length)).safe_then_interruptible( [&delta_stats, &os, &osd_op, this](auto&& m) { return seastar::do_with(interval_set{std::move(m)}, [&delta_stats, &os, &osd_op, this](auto&& extents) { -- 2.47.3