]> 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>
Mon, 7 Mar 2022 12:42:40 +0000 (07:42 -0500)
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>
src/osd/PrimaryLogPG.cc

index fb3f0adb5eefd0cc7ab6ea575061b8f0f109851f..ee033ac362af71dd1abdc08537d279f95c49dc68 100644 (file)
@@ -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<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;
     }