if ( op_ret < 0) {
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_info);
+ if (op_ret < 0) {
+ return;
+ }
if (!store->is_meta_master()) {
bufferlist in_data;
}
}
- op_ret = store->delete_bucket(s->bucket_info, ot);
+ op_ret = store->delete_bucket(s->bucket_info, ot, false);
if (op_ret == -ECANCELED) {
// lost a race, either with mdlog sync or another delete bucket operation.
return true;
}
-
-/**
- * Delete a bucket.
- * bucket: the name of the bucket to delete
- * Returns 0 on success, -ERR# otherwise.
- */
-int RGWRados::delete_bucket(RGWBucketInfo& bucket_info, RGWObjVersionTracker& objv_tracker)
-{
- const rgw_bucket& bucket = bucket_info.bucket;
- librados::IoCtx index_ctx;
- map<int, string> bucket_objs;
- int r = open_bucket_index(bucket_info, index_ctx, bucket_objs);
- if (r < 0)
- return r;
+int RGWRados::check_bucket_empty(RGWBucketInfo& bucket_info)
+{
std::map<string, rgw_bucket_dir_entry> ent_map;
rgw_obj_index_key marker;
string prefix;
do {
#define NUM_ENTRIES 1000
- r = cls_bucket_list(bucket_info, RGW_NO_SHARD, marker, prefix, NUM_ENTRIES, true, ent_map,
+ int r = cls_bucket_list(bucket_info, RGW_NO_SHARD, marker, prefix, NUM_ENTRIES, true, ent_map,
&is_truncated, &marker);
if (r < 0)
return r;
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(RGWBucketInfo& bucket_info, RGWObjVersionTracker& objv_tracker, bool check_empty)
+{
+ const rgw_bucket& bucket = bucket_info.bucket;
+ librados::IoCtx index_ctx;
+ map<int, string> bucket_objs;
+ int r = open_bucket_index(bucket_info, index_ctx, bucket_objs);
+ if (r < 0)
+ return r;
+
+ if (check_empty) {
+ r = check_bucket_empty(bucket_info);
+ if (r < 0) {
+ return r;
+ }
+ }
+
r = rgw_bucket_delete_bucket_obj(this, bucket.tenant, bucket.name, objv_tracker);
if (r < 0)
return r;
return 0;
}
-
int RGWRados::set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner)
{
RGWBucketInfo info;
string *ptag,
ceph::buffer::list *petag,
struct rgw_err *err);
+
+ int check_bucket_empty(RGWBucketInfo& bucket_info);
/**
* Delete a bucket.
* bucket: the name of the bucket to delete
* Returns 0 on success, -ERR# otherwise.
*/
- int delete_bucket(RGWBucketInfo& bucket_info, RGWObjVersionTracker& objv_tracker);
+ int delete_bucket(RGWBucketInfo& bucket_info, RGWObjVersionTracker& objv_tracker, bool check_empty = true);
bool is_meta_master();