From: Zhang Shaowen Date: Mon, 20 Mar 2017 07:19:22 +0000 (+0800) Subject: rgw: delete non-empty buckets in slave zonegroup returns error but the X-Git-Tag: v10.2.10~75^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b786f7815b94e7659a07778a6318ffe5e5079fc0;p=ceph.git rgw: delete non-empty buckets in slave zonegroup returns error but the buckets have actually been deleted. Fixes: http://tracker.ceph.com/issues/19313 Signed-off-by: Zhang Shaowen (cherry picked from commit 4714b17f53a9f30f7f155a69cfbfc682f809b4e4) Conflicts: src/rgw/rgw_op.cc - first argument to delete_bucket() and check_bucket_empty() is "s->bucket" in jewel (master: "s->bucket_info") src/rgw/rgw_rados.cc - RGWRados::delete_bucket() takes bucket instead of bucket_info; adapt RGWRados::check_bucket_empty() to take bucket instead of bucket_info as well src/rgw/rgw_rados.h - ditto --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 3af17ddcdeca..1eb616baf2b8 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2190,6 +2190,11 @@ void RGWDeleteBucket::execute() ldout(s->cct, 1) << "WARNING: failed to sync user stats before bucket delete: op_ret= " << op_ret << dendl; } + op_ret = store->check_bucket_empty(s->bucket); + if (op_ret < 0) { + return; + } + if (!store->is_meta_master()) { bufferlist in_data; op_ret = forward_request_to_master(s, &ot.read_version, store, in_data, @@ -2204,7 +2209,7 @@ void RGWDeleteBucket::execute() } } - op_ret = store->delete_bucket(s->bucket, ot); + op_ret = store->delete_bucket(s->bucket, ot, false); if (op_ret == -ECANCELED) { // lost a race, either with mdlog sync or another delete bucket operation. diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index fd3e54c017c7..9b85af3996e0 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -7388,20 +7388,9 @@ bool RGWRados::is_syncing_bucket_meta(rgw_bucket& bucket) return true; } - -/** - * Delete a bucket. - * bucket: the name of the bucket to delete - * Returns 0 on success, -ERR# otherwise. - */ -int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_tracker) -{ - librados::IoCtx index_ctx; - map bucket_objs; - int r = open_bucket_index(bucket, index_ctx, bucket_objs); - if (r < 0) - return r; +int RGWRados::check_bucket_empty(rgw_bucket& bucket) +{ std::map ent_map; rgw_obj_key marker; string prefix; @@ -7409,7 +7398,7 @@ int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_track do { #define NUM_ENTRIES 1000 - r = cls_bucket_list(bucket, RGW_NO_SHARD, marker, prefix, NUM_ENTRIES, true, ent_map, + int r = cls_bucket_list(bucket, RGW_NO_SHARD, marker, prefix, NUM_ENTRIES, true, ent_map, &is_truncated, &marker); if (r < 0) return r; @@ -7425,7 +7414,29 @@ int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_track return -ENOTEMPTY; } } while (is_truncated); + return 0; +} +/** + * Delete a bucket. + * bucket: the name of the bucket to delete + * Returns 0 on success, -ERR# otherwise. + */ +int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_tracker, bool check_empty) +{ + librados::IoCtx index_ctx; + map bucket_objs; + int r = open_bucket_index(bucket, index_ctx, bucket_objs); + if (r < 0) + return r; + + if (check_empty) { + r = check_bucket_empty(bucket); + if (r < 0) { + return r; + } + } + r = rgw_bucket_delete_bucket_obj(this, bucket.tenant, bucket.name, objv_tracker); if (r < 0) return r; @@ -7447,7 +7458,6 @@ int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_track return 0; } - int RGWRados::set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner) { RGWBucketInfo info; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 6a63a03a6366..3fcdae9055e7 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2621,12 +2621,14 @@ public: string *petag, struct rgw_err *err); + int check_bucket_empty(rgw_bucket& bucket); + /** * Delete a bucket. * bucket: the name of the bucket to delete * Returns 0 on success, -ERR# otherwise. */ - virtual int delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_tracker); + virtual int delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_tracker, bool check_empty = true); bool is_meta_master();