]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: translate sparse_read to read for ecpool
authorKefu Chai <kchai@redhat.com>
Thu, 27 Aug 2015 14:57:49 +0000 (22:57 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 1 Sep 2015 05:49:21 +0000 (13:49 +0800)
Fixes: #12012
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/osd/ReplicatedPG.cc

index c29a2afa706d52824ef2bee417067b506b03f18d..e68fdac15b61b6ad7c175747b49bb1db4a0f5899 100644 (file)
@@ -3660,6 +3660,22 @@ struct FillInExtent : public Context {
   }
 };
 
+struct ToSparseReadResult : public Context {
+  bufferlist& data_bl;
+  ceph_le64& len;
+  ToSparseReadResult(bufferlist& bl, ceph_le64& len):
+    data_bl(bl), len(len) {}
+  void finish(int r) {
+    if (r < 0) return;
+    len = r;
+    bufferlist outdata;
+    map<uint64_t, uint64_t> extents = {{0, r}};
+    ::encode(extents, outdata);
+    ::encode_destructively(data_bl, outdata);
+    data_bl.swap(outdata);
+  }
+};
+
 template<typename V>
 static string list_keys(const map<string, V>& m) {
   string s;
@@ -3886,17 +3902,21 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
     /* map extents */
     case CEPH_OSD_OP_SPARSE_READ:
       tracepoint(osd, do_osd_op_pre_sparse_read, soid.oid.name.c_str(), soid.snap.val, oi.size, oi.truncate_seq, op.extent.offset, op.extent.length, op.extent.truncate_size, op.extent.truncate_seq);
-      if (pool.info.require_rollback()) {
-       result = -EOPNOTSUPP;
+      if (op.extent.truncate_seq) {
+       dout(0) << "sparse_read does not support truncation sequence " << dendl;
+       result = -EINVAL;
        break;
       }
       ++ctx->num_read;
-      {
-        if (op.extent.truncate_seq) {
-          dout(0) << "sparse_read does not support truncation sequence " << dendl;
-          result = -EINVAL;
-          break;
-        }
+      if (pool.info.require_rollback()) {
+       // translate sparse read to a normal one if not supported
+       ctx->pending_async_reads.push_back(
+         make_pair(
+           boost::make_tuple(op.extent.offset, op.extent.length, op.flags),
+           make_pair(&osd_op.outdata, new ToSparseReadResult(osd_op.outdata,
+                                                             op.extent.length))));
+       dout(10) << " async_read (was sparse_read) noted for " << soid << dendl;
+      } else {
        // read into a buffer
        bufferlist bl;
         int total_read = 0;
@@ -3963,11 +3983,10 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
         osd_op.outdata.claim_append(bl);
         ::encode_destructively(data_bl, osd_op.outdata);
 
-       ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(op.extent.length, 10);
-       ctx->delta_stats.num_rd++;
-
        dout(10) << " sparse_read got " << total_read << " bytes from object " << soid << dendl;
       }
+      ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(op.extent.length, 10);
+      ctx->delta_stats.num_rd++;
       break;
 
     case CEPH_OSD_OP_CALL: