]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: bucket link: use data from bucket_info to rewrite bucket_endpoint.
authorMarcus Watts <mwatts@redhat.com>
Sat, 25 Aug 2018 09:48:41 +0000 (05:48 -0400)
committerShilpa Jagannath <smanjara@redhat.com>
Tue, 30 Jul 2019 08:30:45 +0000 (14:00 +0530)
The bucket link command was doing a fetch of the entrypoint late
in the link process.  This makes it harder to do "bucket move"
functionality, because then it would need to know the old
bucket late in the process.  The bucketinfo structure has
all the data elements necessary to recreate the endpoint,
so the changes here arrange to just use that data.

In order to write the object it's also necessary to propagate
xattrs.  The only xattr that seems to be present on the endpoint
is "ceph.objclass.version", so that's what this copies out.
It appears that attribute may be set set separately by cls,
so I'm not sure this is actually necessary.  However, the
old code would have written it, so this code preserves
that behavior.

Fixes: http://tracker.ceph.com/issues/35885
Signed-off-by: Marcus Watts <mwatts@redhat.com>
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h

index f4c664c9a6a9c9bb71516883c6a2b78e228a18f0..de1175e71ad78bbaff9cb13e8cd517eddfc88a22 100644 (file)
 #include "rgw_common.h"
 #include "rgw_reshard.h"
 #include "rgw_lc.h"
+
+// stolen from src/cls/version/cls_version.cc
+#define VERSION_ATTR "ceph.objclass.version"
+
 #include "cls/user/cls_user_types.h"
 
 #define dout_context g_ceph_context
@@ -189,7 +193,8 @@ int rgw_link_bucket(RGWRados* const store,
                     const rgw_user& user_id,
                     rgw_bucket& bucket,
                     ceph::real_time creation_time,
-                    bool update_entrypoint)
+                    bool update_entrypoint,
+                    rgw_ep_info *pinfo)
 {
   int ret;
   string& tenant_name = bucket.tenant;
@@ -207,14 +212,22 @@ int rgw_link_bucket(RGWRados* const store,
   else
     new_bucket.creation_time = creation_time;
 
-  map<string, bufferlist> attrs;
-  RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx();
+  map<string, bufferlist> attrs, *pattrs;
 
   if (update_entrypoint) {
-    ret = store->get_bucket_entrypoint_info(obj_ctx, tenant_name, bucket_name, ep, &ot, NULL, &attrs);
-    if (ret < 0 && ret != -ENOENT) {
-      ldout(store->ctx(), 0) << "ERROR: store->get_bucket_entrypoint_info() returned: "
-                             << cpp_strerror(-ret) << dendl;
+    if (pinfo) {
+      ep = pinfo->ep;
+      pattrs = &pinfo->attrs;
+    } else {
+      RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx();
+
+      ret = store->get_bucket_entrypoint_info(obj_ctx,
+               tenant_name, bucket_name, ep, &ot, NULL, &attrs);
+      if (ret < 0 && ret != -ENOENT) {
+       ldout(store->ctx(), 0) << "ERROR: store->get_bucket_entrypoint_info() returned: "
+                              << cpp_strerror(-ret) << dendl;
+      }
+      pattrs = &attrs;
     }
   }
 
@@ -235,7 +248,7 @@ int rgw_link_bucket(RGWRados* const store,
   ep.linked = true;
   ep.owner = user_id;
   ep.bucket = bucket;
-  ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, real_time(), &attrs);
+  ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, real_time(), pattrs);
   if (ret < 0)
     goto done_err;
 
@@ -921,8 +934,22 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state,
       return r;
     }
 
+    RGWBucketEntryPoint ep;
+    ep.bucket = bucket_info.bucket;
+    ep.owner = user_info.user_id;
+    ep.creation_time = bucket_info.creation_time;
+    ep.linked = true;
+    map<string, bufferlist> ep_attrs;
+    // XXX I am not convinced this is at all necessary; but previous
+    // versions would have found and copied VERSION_ATTR so I will
+    // do likewise for now...  mdw 20180825
+    auto version_iter = attrs.find(VERSION_ATTR);
+    if (version_iter != attrs.end())
+      ep_attrs[VERSION_ATTR] = version_iter->second;
+    rgw_ep_info ep_data{ep, ep_attrs};
+
     r = rgw_link_bucket(store, user_info.user_id, bucket_info.bucket,
-                        ceph::real_time());
+                        ceph::real_time(), true, &ep_data);
     if (r < 0) {
       set_err_msg(err_msg, "failed to relink bucket");
       return r;
index e9528b9c3e64acd8761f485b2e3c763f27147d3d..166f2e4a0619e80dd3f9334d63db34a1f1ce0ef4 100644 (file)
@@ -200,11 +200,19 @@ extern int rgw_read_user_buckets(RGWRados *store,
                                 bool* is_truncated,
                                  uint64_t default_amount = 1000);
 
+struct rgw_ep_info {
+    RGWBucketEntryPoint &ep;
+    map<string, bufferlist>& attrs;
+    rgw_ep_info(RGWBucketEntryPoint &ep, map<string, bufferlist>& attrs)
+       : ep(ep), attrs(attrs) { }
+};
+
 extern int rgw_link_bucket(RGWRados* store,
                            const rgw_user& user_id,
                            rgw_bucket& bucket,
                            ceph::real_time creation_time,
-                           bool update_entrypoint = true);
+                           bool update_entrypoint = true,
+                           rgw_ep_info *pinfo = nullptr);
 extern int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id,
                              const string& tenant_name, const string& bucket_name, bool update_entrypoint = true);