]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: allow sparse reads with a non-zero truncate-seq
authorJeff Layton <jlayton@redhat.com>
Thu, 17 Feb 2022 12:41:31 +0000 (07:41 -0500)
committerJeff Layton <jlayton@redhat.com>
Thu, 31 Mar 2022 16:54:25 +0000 (12:54 -0400)
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 <jlayton@redhat.com>
(cherry picked from commit 58f3e8bb98b966935898ef1c3eed61be7768d513)

src/osd/PrimaryLogPG.cc

index 4fde8b560d6388ab890752484f03c054f69c091f..677aef16552d906d9d73723df0ffc934853e6de2 100644 (file)
@@ -5859,22 +5859,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(
@@ -5898,7 +5902,7 @@ int PrimaryLogPG::do_sparse_read(OpContext *ctx, OSDOp& osd_op) {
     map<uint64_t, uint64_t> 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;
     }