]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson: add support for basic write path, part 2.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 29 Apr 2019 18:59:57 +0000 (20:59 +0200)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Wed, 8 May 2019 05:44:11 +0000 (07:44 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/crimson/os/Transaction.h
src/crimson/os/cyan_store.cc
src/crimson/osd/pg.cc
src/crimson/osd/pg_backend.cc
src/crimson/osd/pg_backend.h

index a1841ef7e1776a12ece574ec536584f7d848d387..3187bad706b7b6c2aa8c07ddf18e97d8755be580 100644 (file)
@@ -867,7 +867,7 @@ public:
   /// Set an xattr of an object
   void setattr(const coll_t& cid, const ghobject_t& oid,
               const char* name,
-              bufferlist& val) {
+              bufferlist&& val) {
     string n(name);
     setattr(cid, oid, n, val);
   }
index 64e7637d9489becd6dac4a6d099d86f157e2049f..4319fc14853185dc23f5ff027a604567bb176c56 100644 (file)
@@ -170,8 +170,8 @@ seastar::future<ceph::bufferptr> CyanStore::get_attr(CollectionRef c,
   if (auto found = o->xattr.find(name); found != o->xattr.end()) {
     return seastar::make_ready_future<ceph::bufferptr>(found->second);
   } else {
-    throw std::runtime_error(fmt::format("attr does not exist: {}/{}",
-                                         oid, name));
+    return seastar::make_exception_future<ceph::bufferptr>(
+      EnoentException(fmt::format("attr does not exist: {}/{}", oid, name)));
   }
 }
 
index d3912f1e1b659184e2602661fd8def6de1abfd49..6cae617f84d88c0c9d15c3f20b7a694b4d36c252 100644 (file)
@@ -1015,8 +1015,13 @@ seastar::future<Ref<MOSDOpReply>> PG::do_osd_ops(Ref<MOSDOp> m)
       // TODO: issue requests in parallel if they don't write,
       // with writes being basically a synchronization barrier
       return seastar::do_for_each(std::begin(m->ops), std::end(m->ops),
-                                  [m,&txn,this,os=std::move(os)](OSDOp& osd_op) {
+                                  [m,&txn,this,os](OSDOp& osd_op) {
         return do_osd_op(*os, osd_op, txn);
+      }).then([m,&txn,this,os=std::move(os)] {
+        // XXX: the entire lambda can be scheduled conditionally
+        // XXX: I'm not txn.empty() is what we want here
+        return !txn.empty() ? backend->store_object_state(os, *m, txn)
+                            : seastar::now();
       });
     }).then([&] {
       return txn.empty() ? seastar::now()
index 11459db34ec7067bd63ff8cfe1e2340bcf20b7ca..fa415d988fcfcba33697cbb2f527d6ddd4dd328d 100644 (file)
@@ -4,6 +4,8 @@
 #include <fmt/ostream.h>
 #include <seastar/core/print.hh>
 
+#include "messages/MOSDOp.h"
+
 #include "crimson/os/cyan_collection.h"
 #include "crimson/os/cyan_object.h"
 #include "crimson/os/cyan_store.h"
@@ -149,6 +151,37 @@ PGBackend::_load_ss(const hobject_t& oid)
   });
 }
 
+seastar::future<>
+PGBackend::store_object_state(
+  //const hobject_t& oid,
+  const cached_os_t os,
+  const MOSDOp& m,
+  ceph::os::Transaction& txn)
+{
+  if (os->exists) {
+#if 0
+    os.oi.version = ctx->at_version;
+    os.oi.prior_version = ctx->obs->oi.version;
+#endif
+
+    os->oi.last_reqid = m.get_reqid();
+    os->oi.mtime = m.get_mtime();
+    os->oi.local_mtime = ceph_clock_now();
+
+    // object_info_t
+    {
+      ceph::bufferlist osv;
+      encode(os->oi, osv, 0);
+      // TODO: get_osdmap()->get_features(CEPH_ENTITY_TYPE_OSD, nullptr));
+      txn.setattr(coll->cid, ghobject_t{os->oi.soid}, OI_ATTR, std::move(osv));
+    }
+  } else {
+    // reset cached ObjectState without enforcing eviction
+    os->oi = object_info_t(os->oi.soid);
+  }
+  return seastar::now();
+}
+
 seastar::future<>
 PGBackend::evict_object_state(const hobject_t& oid)
 {
@@ -198,6 +231,25 @@ seastar::future<bufferlist> PGBackend::read(const object_info_t& oi,
     });
 }
 
+bool PGBackend::maybe_create_new_object(
+  ObjectState& os,
+  ceph::os::Transaction& txn)
+{
+  if (!os.exists) {
+    ceph_assert(!os.oi.is_whiteout());
+    os.exists = true;
+    os.oi.new_object();
+
+    txn.touch(coll->cid, ghobject_t{os.oi.soid});
+    // TODO: delta_stats.num_objects++
+    return false;
+  } else if (os.oi.is_whiteout()) {
+    os.oi.clear_flag(object_info_t::FLAG_WHITEOUT);
+    // TODO: delta_stats.num_whiteouts--
+  }
+  return true;
+}
+
 seastar::future<> PGBackend::writefull(
   ObjectState& os,
   const OSDOp& osd_op,
@@ -208,12 +260,14 @@ seastar::future<> PGBackend::writefull(
     throw ::invalid_argument();
   }
 
-  if (os.exists && op.extent.length < os.oi.size) {
+  const bool existing = maybe_create_new_object(os, txn);
+  if (existing && op.extent.length < os.oi.size) {
     txn.truncate(coll->cid, ghobject_t{os.oi.soid}, op.extent.length);
   }
   if (op.extent.length) {
     txn.write(coll->cid, ghobject_t{os.oi.soid}, 0, op.extent.length,
               osd_op.indata, op.flags);
+    os.oi.size = op.extent.length;
   }
   return seastar::now();
 }
index 003ef0151f198ea533b5b2f27baa640d2097fd54..bb44e54052c8e1a11c9867e969b1790b7c9eae4e 100644 (file)
@@ -33,6 +33,9 @@ public:
                                           ceph::os::CyanStore* store,
                                           const ec_profile_t& ec_profile);
   using cached_os_t = boost::local_shared_ptr<ObjectState>;
+  seastar::future<> store_object_state(const cached_os_t os,
+                                      const MOSDOp& m,
+                                      ceph::os::Transaction& txn);
   seastar::future<cached_os_t> get_object_state(const hobject_t& oid);
   seastar::future<> evict_object_state(const hobject_t& oid);
   seastar::future<bufferlist> read(const object_info_t& oi,
@@ -62,4 +65,5 @@ private:
                                            size_t offset,
                                            size_t length,
                                            uint32_t flags) = 0;
+  bool maybe_create_new_object(ObjectState& os, ceph::os::Transaction& txn);
 };