1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
5 * Ceph - scalable distributed file system
7 * Copyright (C) 2019 Red Hat, Inc.
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
18 #include <system_error>
22 #include "common/errno.h"
25 #include "rgw_bucket.h"
26 #include "rgw_multi.h"
28 #define dout_subsys ceph_subsys_rgw
32 int RGWRadosUser::list_buckets(const string
& marker
, const string
& end_marker
,
33 uint64_t max
, bool need_stats
, RGWBucketList
&buckets
)
36 bool is_truncated
= false;
39 ret
= store
->ctl()->user
->list_buckets(info
.user_id
, marker
, end_marker
, max
,
40 need_stats
, &ulist
, &is_truncated
);
44 buckets
.set_truncated(is_truncated
);
45 for (const auto& ent
: ulist
.get_buckets()) {
46 RGWRadosBucket
*rb
= new RGWRadosBucket(this->store
, *this, ent
.second
);
53 RGWBucketList::~RGWBucketList()
55 for (auto itr
= buckets
.begin(); itr
!= buckets
.end(); itr
++) {
61 RGWBucket
* RGWRadosUser::add_bucket(rgw_bucket
& bucket
,
62 ceph::real_time creation_time
)
67 int RGWRadosUser::get_by_id(rgw_user id
, optional_yield y
)
70 return store
->ctl()->user
->get_info_by_uid(id
, &info
, y
);
73 RGWObject
*RGWRadosBucket::create_object(const rgw_obj_key
&key
)
76 object
= new RGWRadosObject(store
, key
);
82 int RGWRadosBucket::remove_bucket(bool delete_children
, optional_yield y
)
85 map
<RGWObjCategory
, RGWStorageStats
> stats
;
86 std::vector
<rgw_bucket_dir_entry
> objs
;
87 map
<string
, bool> common_prefixes
;
88 string bucket_ver
, master_ver
;
90 ret
= get_bucket_info(y
);
94 ret
= get_bucket_stats(info
, RGW_NO_SHARD
, &bucket_ver
, &master_ver
, stats
);
98 RGWRados::Bucket
target(store
->getRados(), info
);
99 RGWRados::Bucket::List
list_op(&target
);
102 list_op
.params
.list_versions
= true;
103 list_op
.params
.allow_unordered
= true;
105 bool is_truncated
= false;
109 ret
= list_op
.list_objects(max
, &objs
, &common_prefixes
, &is_truncated
, null_yield
);
113 if (!objs
.empty() && !delete_children
) {
114 lderr(store
->ctx()) << "ERROR: could not remove non-empty bucket " << ent
.bucket
.name
<< dendl
;
118 for (const auto& obj
: objs
) {
119 rgw_obj_key
key(obj
.key
);
121 ret
= rgw_remove_object(store
, info
, ent
.bucket
, key
);
122 if (ret
< 0 && ret
!= -ENOENT
) {
126 } while(is_truncated
);
128 string prefix
, delimiter
;
130 ret
= abort_bucket_multiparts(store
, store
->ctx(), info
, prefix
, delimiter
);
135 ret
= store
->ctl()->bucket
->sync_user_stats(info
.owner
, info
);
137 ldout(store
->ctx(), 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret
<< dendl
;
140 RGWObjVersionTracker objv_tracker
;
142 // if we deleted children above we will force delete, as any that
143 // remain is detrius from a prior bug
144 ret
= store
->getRados()->delete_bucket(info
, objv_tracker
, null_yield
, !delete_children
);
146 lderr(store
->ctx()) << "ERROR: could not remove bucket " <<
147 ent
.bucket
.name
<< dendl
;
151 ret
= store
->ctl()->bucket
->unlink_bucket(info
.owner
, ent
.bucket
, null_yield
, false);
153 lderr(store
->ctx()) << "ERROR: unable to remove user bucket information" << dendl
;
159 int RGWRadosBucket::get_bucket_info(optional_yield y
)
161 return store
->getRados()->get_bucket_info(store
->svc(), ent
.bucket
.tenant
, ent
.bucket
.name
, info
,
165 int RGWRadosBucket::get_bucket_stats(RGWBucketInfo
& bucket_info
, int shard_id
,
166 std::string
*bucket_ver
, std::string
*master_ver
,
167 std::map
<RGWObjCategory
, RGWStorageStats
>& stats
,
168 std::string
*max_marker
, bool *syncstopped
)
170 return store
->getRados()->get_bucket_stats(bucket_info
, shard_id
, bucket_ver
, master_ver
, stats
, max_marker
, syncstopped
);
173 int RGWRadosBucket::read_bucket_stats(optional_yield y
)
175 return store
->ctl()->bucket
->read_bucket_stats(ent
.bucket
, &ent
, y
);
178 int RGWRadosBucket::sync_user_stats()
180 return store
->ctl()->bucket
->sync_user_stats(user
.info
.user_id
, info
, &ent
);
183 int RGWRadosBucket::update_container_stats(void)
186 map
<std::string
, RGWBucketEnt
> m
;
188 m
[ent
.bucket
.name
] = ent
;
189 ret
= store
->getRados()->update_containers_stats(m
);
195 map
<string
, RGWBucketEnt
>::iterator iter
= m
.find(ent
.bucket
.name
);
199 ent
.count
= iter
->second
.count
;
200 ent
.size
= iter
->second
.size
;
201 ent
.size_rounded
= iter
->second
.size_rounded
;
202 ent
.placement_rule
= std::move(iter
->second
.placement_rule
);
207 int RGWRadosBucket::check_bucket_shards(void)
209 return store
->getRados()->check_bucket_shards(info
, ent
.bucket
, get_count());
212 int RGWRadosBucket::link(RGWUser
* new_user
, optional_yield y
)
214 RGWBucketEntryPoint ep
;
215 ep
.bucket
= ent
.bucket
;
216 ep
.owner
= new_user
->get_user();
217 ep
.creation_time
= get_creation_time();
219 map
<string
, bufferlist
> ep_attrs
;
220 rgw_ep_info ep_data
{ep
, ep_attrs
};
222 return store
->ctl()->bucket
->link_bucket(new_user
->get_user(), info
.bucket
,
223 ceph::real_time(), y
, true, &ep_data
);
226 int RGWRadosBucket::unlink(RGWUser
* new_user
, optional_yield y
)
231 int RGWRadosBucket::chown(RGWUser
* new_user
, RGWUser
* old_user
, optional_yield y
)
235 return store
->ctl()->bucket
->chown(store
, info
, new_user
->get_user(),
236 old_user
->get_display_name(), obj_marker
, y
);
239 bool RGWRadosBucket::is_owner(RGWUser
* user
)
241 get_bucket_info(null_yield
);
243 return (info
.owner
.compare(user
->get_user()) == 0);
246 int RGWRadosBucket::set_acl(RGWAccessControlPolicy
&acl
, optional_yield y
)
253 return store
->ctl()->bucket
->set_acl(acl
.get_owner(), ent
.bucket
, info
, aclbl
, null_yield
);
256 RGWUser
*RGWRadosStore::get_user(const rgw_user
&u
)
258 return new RGWRadosUser(this, u
);
261 //RGWBucket *RGWRadosStore::create_bucket(RGWUser &u, const rgw_bucket &b)
264 //bucket = new RGWRadosBucket(this, u, b);
270 void RGWRadosStore::finalize(void) {
275 int RGWRadosStore::get_bucket(RGWUser
& u
, const rgw_bucket
& b
, RGWBucket
** bucket
)
282 bp
= new RGWRadosBucket(this, u
, b
);
286 ret
= bp
->get_bucket_info(null_yield
);
296 } // namespace rgw::sal
298 rgw::sal::RGWRadosStore
*RGWStoreManager::init_storage_provider(CephContext
*cct
, bool use_gc_thread
, bool use_lc_thread
, bool quota_threads
, bool run_sync_thread
, bool run_reshard_thread
, bool use_cache
)
300 RGWRados
*rados
= new RGWRados
;
301 rgw::sal::RGWRadosStore
*store
= new rgw::sal::RGWRadosStore();
303 store
->setRados(rados
);
304 rados
->set_store(store
);
306 if ((*rados
).set_use_cache(use_cache
)
307 .set_run_gc_thread(use_gc_thread
)
308 .set_run_lc_thread(use_lc_thread
)
309 .set_run_quota_threads(quota_threads
)
310 .set_run_sync_thread(run_sync_thread
)
311 .set_run_reshard_thread(run_reshard_thread
)
312 .initialize(cct
) < 0) {
320 rgw::sal::RGWRadosStore
*RGWStoreManager::init_raw_storage_provider(CephContext
*cct
)
322 RGWRados
*rados
= new RGWRados
;
323 rgw::sal::RGWRadosStore
*store
= new rgw::sal::RGWRadosStore();
325 store
->setRados(rados
);
326 rados
->set_store(store
);
328 rados
->set_context(cct
);
330 int ret
= rados
->init_svc(true);
332 ldout(cct
, 0) << "ERROR: failed to init services (ret=" << cpp_strerror(-ret
) << ")" << dendl
;
337 if (rados
->init_rados() < 0) {
345 void RGWStoreManager::close_storage(rgw::sal::RGWRadosStore
*store
)