From acf876ad88a42dde634523fa80daf5bb11d36b10 Mon Sep 17 00:00:00 2001 From: Abhishek Varshney Date: Fri, 16 Jun 2017 18:23:16 +0530 Subject: [PATCH] rgw: fix leaks with incomplete multiparts in delete bucket Fixes: http://tracker.ceph.com/issues/17164 Signed-off-by: Abhishek Varshney --- src/rgw/rgw_bucket.cc | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 97ddb192c2d0..230614457561 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -20,6 +20,7 @@ #include "rgw_bucket.h" #include "rgw_user.h" #include "rgw_string.h" +#include "rgw_multi.h" #include "include/rados/librados.hpp" // until everything is moved from rgw_common @@ -530,32 +531,39 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children) if (ret < 0) return ret; - RGWRados::Bucket target(store, info); RGWRados::Bucket::List list_op(&target); + CephContext *cct = store->ctx(); + int max = 1000; list_op.params.list_versions = true; - if (delete_children) { - int max = 1000; + do { + objs.clear(); - do { - objs.clear(); + ret = list_op.list_objects(max, &objs, &common_prefixes, NULL); + if (ret < 0) + return ret; + + if (!objs.empty() && !delete_children) { + lderr(store->ctx()) << "ERROR: could not remove non-empty bucket " << bucket.name << dendl; + return -ENOTEMPTY; + } - ret = list_op.list_objects(max, &objs, &common_prefixes, NULL); + for (const auto& obj : objs) { + rgw_obj_key key(obj.key); + ret = rgw_remove_object(store, info, bucket, key); if (ret < 0) return ret; + } - std::vector::iterator it = objs.begin(); - for (; it != objs.end(); ++it) { - rgw_obj_key key(it->key); - ret = rgw_remove_object(store, info, bucket, key); - if (ret < 0) - return ret; - } + } while (!objs.empty()); - } while (!objs.empty()); + string prefix, delimiter; + ret = abort_bucket_multiparts(store, cct, info, prefix, delimiter); + if (ret < 0) { + return ret; } ret = rgw_bucket_sync_user_stats(store, bucket.tenant, info); @@ -611,6 +619,7 @@ int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket, map common_prefixes; RGWBucketInfo info; RGWObjectCtx obj_ctx(store); + CephContext *cct = store->ctx(); string bucket_ver, master_ver; @@ -622,6 +631,12 @@ int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket, if (ret < 0) return ret; + string prefix, delimiter; + + ret = abort_bucket_multiparts(store, cct, info, prefix, delimiter); + if (ret < 0) { + return ret; + } RGWRados::Bucket target(store, info); RGWRados::Bucket::List list_op(&target); -- 2.47.3