From de7a8679af93457c10bf514c17a7cfc5327e745c Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Wed, 28 Dec 2016 17:14:35 +0100 Subject: [PATCH] rgw: bucket linking stores also the info about a placement rule. Fixes: http://tracker.ceph.com/issues/17932 Signed-off-by: Radoslaw Zarzynski --- src/cls/user/cls_user.cc | 7 ++++++- src/rgw/rgw_bucket.cc | 27 ++++++++++++++++++++++----- src/rgw/rgw_bucket.h | 7 ++++++- src/rgw/rgw_op.cc | 6 +++--- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/cls/user/cls_user.cc b/src/cls/user/cls_user.cc index 7912578aa36..b4d6001fae1 100644 --- a/src/cls/user/cls_user.cc +++ b/src/cls/user/cls_user.cc @@ -157,13 +157,18 @@ static int cls_user_set_buckets_info(cls_method_context_t hctx, bufferlist *in, CLS_LOG(20, "storing entry for key=%s size=%lld count=%lld", key.c_str(), (long long)update_entry.size, (long long)update_entry.count); + // Update bucket's placement rule info only when linking bucket, not on + // usage stats change. */ + if (op.add) { + entry.placement_rule = update_entry.placement_rule; + } + // sync entry stats when not an op.add, as when the case is op.add if its a // new entry we already have copied update_entry earlier, OTOH, for an existing entry // we end up clobbering the existing stats for the bucket if (!op.add){ apply_entry_stats(update_entry, &entry); } - entry.user_stats_sync = true; ret = write_entry(hctx, key, entry); diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 23981b44025..d321446fb13 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -180,13 +180,19 @@ int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const return 0; } -int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, real_time creation_time, bool update_entrypoint) +int rgw_link_bucket(RGWRados* const store, + const rgw_user& user_id, + rgw_bucket& bucket, + ceph::real_time creation_time, + std::string placement_rule, + bool update_entrypoint) { int ret; string& tenant_name = bucket.tenant; string& bucket_name = bucket.name; cls_user_bucket_entry new_bucket; + new_bucket.placement_rule = placement_rule; RGWBucketEntryPoint ep; RGWObjVersionTracker ot; @@ -478,7 +484,9 @@ void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, cout << "bucket info mismatch: expected " << actual_bucket << " got " << bucket << std::endl; if (fix) { cout << "fixing" << std::endl; - r = rgw_link_bucket(store, user_id, actual_bucket, bucket_info.creation_time); + r = rgw_link_bucket(store, user_id, actual_bucket, + bucket_info.creation_time, + bucket_info.placement_rule); if (r < 0) { cerr << "failed to fix bucket: " << cpp_strerror(-r) << std::endl; } @@ -895,7 +903,8 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg) return r; } - r = rgw_link_bucket(store, user_info.user_id, bucket_info.bucket, real_time()); + r = rgw_link_bucket(store, user_info.user_id, bucket_info.bucket, + ceph::real_time(), bucket_info.placement_rule); if (r < 0) { return r; } @@ -2118,9 +2127,17 @@ public: /* link bucket */ if (be.linked) { - ret = rgw_link_bucket(store, be.owner, be.bucket, be.creation_time, false); + RGWBucketInfo bucket_info; + ret = store->get_bucket_info(obj_ctx, tenant_name, bucket_name, + bucket_info, nullptr, nullptr); + if (ret < 0) { + return ret; + } + ret = rgw_link_bucket(store, be.owner, be.bucket, be.creation_time, + bucket_info.placement_rule, false); } else { - ret = rgw_unlink_bucket(store, be.owner, be.bucket.tenant, be.bucket.name, false); + ret = rgw_unlink_bucket(store, be.owner, be.bucket.tenant, + be.bucket.name, false); } return ret; diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 38b384aa483..9ee89b3784a 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -176,7 +176,12 @@ extern int rgw_read_user_buckets(RGWRados *store, bool* is_truncated, uint64_t default_amount = 1000); -extern int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, real_time creation_time, bool update_entrypoint = true); +extern int rgw_link_bucket(RGWRados* store, + const rgw_user& user_id, + rgw_bucket& bucket, + ceph::real_time creation_time, + std::string placement_rule, + bool update_entrypoint = true); extern int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id, const string& tenant_name, const string& bucket_name, bool update_entrypoint = true); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index e6937ada2f3..a014aee7263 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2708,7 +2708,7 @@ void RGWCreateBucket::execute() } op_ret = rgw_link_bucket(store, s->user->user_id, s->bucket, - info.creation_time, false); + info.creation_time, info.placement_rule, false); if (op_ret && !existed && op_ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ op_ret = rgw_unlink_bucket(store, s->user->user_id, s->bucket.tenant, @@ -6172,8 +6172,8 @@ int RGWBulkUploadOp::handle_dir(const boost::string_ref path) bucket = out_info.bucket; } - op_ret = rgw_link_bucket(store, s->user->user_id, bucket, - out_info.creation_time, false); + op_ret = rgw_link_bucket(store, s->user->user_id,bucket, out_info.creation_time, + out_info.placement_rule, false); if (op_ret && !existed && op_ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ op_ret = rgw_unlink_bucket(store, s->user->user_id, -- 2.39.5