]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: check truncate size in sparse_read 46587/head
authorchunmei-liu <chunmei.liu@intel.com>
Thu, 9 Jun 2022 07:44:01 +0000 (00:44 -0700)
committerchunmei-liu <chunmei.liu@intel.com>
Wed, 22 Jun 2022 00:39:52 +0000 (17:39 -0700)
Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
src/crimson/osd/pg_backend.cc

index 829b8ea07c93027b3e6879cac8d8536e46ef3d7a..5460e8bfd7129e71cbb0f966525686ee9e0c3277 100644 (file)
@@ -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<uint64_t>{std::move(m)},
                            [&delta_stats, &os, &osd_op, this](auto&& extents) {