]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: `SimpleRadosWriteAttrsCR` uses an async RADOS call
authorAdam C. Emerson <aemerson@redhat.com>
Wed, 24 Aug 2022 19:24:09 +0000 (15:24 -0400)
committerAdam C. Emerson <aemerson@redhat.com>
Thu, 12 Jan 2023 23:05:41 +0000 (18:05 -0500)
Don't go through the 'system object' cache. This also saves us the use
of the RADOS async completion processor.

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
src/rgw/driver/rados/rgw_cr_rados.h
src/rgw/driver/rados/rgw_data_sync.cc
src/test/rgw/rgw_cr_test.cc

index f4362e6b2f28d916adb5746f8a06a0bb81d53ffa..778f66fa2539bcf32dc442ffd1fb7a36c68b83ef 100644 (file)
@@ -572,51 +572,69 @@ public:
 };
 
 class RGWSimpleRadosWriteAttrsCR : public RGWSimpleCoroutine {
-  const DoutPrefixProvider *dpp;
-  RGWAsyncRadosProcessor *async_rados;
-  RGWSI_SysObj *svc;
-  RGWObjVersionTracker *objv_tracker;
-
+  const DoutPrefixProvider* dpp;
+  rgw::sal::RadosStore* const store;
+  RGWObjVersionTracker* objv_tracker;
   rgw_raw_obj obj;
   std::map<std::string, bufferlist> attrs;
   bool exclusive;
-  RGWAsyncPutSystemObjAttrs *req = nullptr;
+
+  rgw_rados_ref ref;
+  boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
+
 
 public:
-  RGWSimpleRadosWriteAttrsCR(const DoutPrefixProvider *_dpp,
-                             RGWAsyncRadosProcessor *_async_rados,
-                             RGWSI_SysObj *_svc, const rgw_raw_obj& _obj,
-                             std::map<std::string, bufferlist> _attrs,
-                             RGWObjVersionTracker *objv_tracker = nullptr,
+  RGWSimpleRadosWriteAttrsCR(const DoutPrefixProviderdpp,
+                            rgw::sal::RadosStore* const store,
+                             rgw_raw_obj obj,
+                             std::map<std::string, bufferlist> attrs,
+                             RGWObjVersionTrackerobjv_tracker = nullptr,
                              bool exclusive = false)
-                            : RGWSimpleCoroutine(_svc->ctx()), dpp(_dpp), async_rados(_async_rados),
-      svc(_svc), objv_tracker(objv_tracker), obj(_obj),
-      attrs(std::move(_attrs)), exclusive(exclusive) {
-  }
-  ~RGWSimpleRadosWriteAttrsCR() override {
-    request_cleanup();
-  }
+                            : RGWSimpleCoroutine(store->ctx()), dpp(dpp),
+                              store(store), objv_tracker(objv_tracker),
+                              obj(std::move(obj)), attrs(std::move(attrs)),
+                              exclusive(exclusive) {}
 
-  void request_cleanup() override {
-    if (req) {
-      req->finish();
-      req = NULL;
+  int send_request(const DoutPrefixProvider *dpp) override {
+    int r = store->getRados()->get_raw_obj_ref(dpp, obj, &ref);
+    if (r < 0) {
+      ldpp_dout(dpp, -1) << "ERROR: failed to get ref for (" << obj << ") ret="
+                        << r << dendl;
+      return r;
     }
-  }
 
-  int send_request(const DoutPrefixProvider *dpp) override {
-    req = new RGWAsyncPutSystemObjAttrs(dpp, this, stack->create_completion_notifier(),
-                                  svc, objv_tracker, obj, std::move(attrs),
-                                   exclusive);
-    async_rados->queue(req);
-    return 0;
+    set_status() << "sending request";
+
+    librados::ObjectWriteOperation op;
+    if (exclusive) {
+      op.create(true);
+    }
+    if (objv_tracker) {
+      objv_tracker->prepare_op_for_write(&op);
+    }
+
+    for (const auto& [name, bl] : attrs) {
+      if (!bl.length())
+       continue;
+      op.setxattr(name.c_str(), bl);
+    }
+
+    cn = stack->create_completion_notifier();
+    if (!op.size()) {
+      cn->cb();
+      return 0;
+    }
+
+    return ref.pool.ioctx().aio_operate(ref.obj.oid, cn->completion(), &op);
   }
 
   int request_complete() override {
-    if (objv_tracker) { // copy the updated version
-      *objv_tracker = req->objv_tracker;
+    int ret = cn->completion()->get_return_value();
+    set_status() << "request complete; ret=" << ret;
+    if (ret >= 0 && objv_tracker) {
+      objv_tracker->apply_write();
     }
-    return req->get_ret_status();
+    return ret;
   }
 };
 
index c030d6ddc4d3bf14c0631a1648e96ec23c678232..1b5ad619beff0a59506a9bc4aa5840b62a34f55a 100644 (file)
@@ -3212,7 +3212,7 @@ public:
 
         map<string, bufferlist> attrs;
         status.encode_all_attrs(attrs);
-        call(new RGWSimpleRadosWriteAttrsCR(dpp, sync_env->async_rados, sync_env->svc->sysobj,
+        call(new RGWSimpleRadosWriteAttrsCR(dpp, sync_env->driver,
                                             obj, attrs, &objv_tracker, exclusive));
       }
 
@@ -4065,7 +4065,7 @@ class RGWWriteBucketShardIncSyncStatus : public RGWCoroutine {
     reenter(this) {
       sync_marker.encode_attr(attrs);
 
-      yield call(new RGWSimpleRadosWriteAttrsCR(sync_env->dpp, sync_env->async_rados, sync_env->svc->sysobj,
+      yield call(new RGWSimpleRadosWriteAttrsCR(sync_env->dpp, sync_env->driver,
                                                 obj, attrs, &objv_tracker));
       if (retcode < 0) {
         return set_cr_error(retcode);
index 957c625574f60013967e0fa03301edfa796bdc30..b53d0655923b4b1ea2037d3aabc65a93e047d1b8 100644 (file)
@@ -267,6 +267,42 @@ TEST(Write, ObjV) {
   ASSERT_EQ(-ECANCELED, r);
 }
 
+TEST(WriteAttrs, Attrs) {
+  TempPool pool;
+  auto oid = "object"s;
+  bufferlist bl;
+  bl.append("I'm some data.");
+  std::map<std::string, bufferlist> wrattrs {
+    { "foo", bl }, { "bar", bl }, { "baz", bl }
+  };
+  auto r = run(new RGWSimpleRadosWriteAttrsCR(dpp(), store, {pool, oid},
+                                             wrattrs, nullptr, true));
+  ASSERT_EQ(0, r);
+  std::map<std::string, bufferlist> rdattrs;
+  librados::IoCtx ioctx(pool);
+  r = ioctx.getxattrs(oid, rdattrs);
+  ASSERT_EQ(0, r);
+  ASSERT_EQ(wrattrs, rdattrs);
+}
+
+TEST(WriteAttrs, Empty) {
+  TempPool pool;
+  auto oid = "object"s;
+  bufferlist bl;
+  std::map<std::string, bufferlist> wrattrs {
+    { "foo", bl }, { "bar", bl }, { "baz", bl }
+  };
+  // With an empty bufferlist all attributes should be skipped.
+  auto r = run(new RGWSimpleRadosWriteAttrsCR(dpp(), store, {pool, oid},
+                                             wrattrs, nullptr, true));
+  ASSERT_EQ(0, r);
+  std::map<std::string, bufferlist> rdattrs;
+  librados::IoCtx ioctx(pool);
+  r = ioctx.getxattrs(oid, rdattrs);
+  ASSERT_EQ(0, r);
+  ASSERT_TRUE(rdattrs.empty());
+}
+
 int main(int argc, const char **argv)
 {
   auto args = argv_to_vec(argc, argv);