From: Yehuda Sadeh Date: Thu, 9 Jan 2014 00:39:19 +0000 (-0800) Subject: rgw: pass bucket owner all around X-Git-Tag: v0.78~270^2~28 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5612ded3b1fe7501340ddb72d6ef041c26b92ffe;p=ceph.git rgw: pass bucket owner all around User quota operations require that we know who the actual user we do the operation on is. Pass that info when creating new object and when removing objects. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index faf0fd139b61..b739fcd7ef4b 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -539,10 +539,9 @@ public: } }; -static int init_bucket(string& bucket_name, rgw_bucket& bucket) +static int init_bucket(string& bucket_name, RGWBucketInfo& bucket_info, rgw_bucket& bucket) { if (!bucket_name.empty()) { - RGWBucketInfo bucket_info; int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL); if (r < 0) { cerr << "could not get bucket info for bucket=" << bucket_name << std::endl; @@ -1450,7 +1449,8 @@ int main(int argc, char **argv) if (bucket_name.empty()) { RGWBucketAdminOp::info(store, bucket_op, f); } else { - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -1774,12 +1774,13 @@ next: } if (opt_cmd == OPT_OBJECT_RM) { - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = rgw_remove_object(store, bucket, object); + ret = rgw_remove_object(store, bucket_info.owner, bucket, object); if (ret < 0) { cerr << "ERROR: object remove returned: " << cpp_strerror(-ret) << std::endl; @@ -1788,7 +1789,8 @@ next: } if (opt_cmd == OPT_OBJECT_UNLINK) { - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -1803,7 +1805,8 @@ next: } if (opt_cmd == OPT_OBJECT_STAT) { - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -2112,7 +2115,8 @@ next: cerr << "ERROR: bucket not specified" << std::endl; return -EINVAL; } - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -2151,7 +2155,8 @@ next: cerr << "ERROR: bucket not specified" << std::endl; return -EINVAL; } - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -2331,7 +2336,8 @@ next: cerr << "ERROR: bucket not specified" << std::endl; return -EINVAL; } - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -2381,7 +2387,8 @@ next: cerr << "ERROR: bucket not specified" << std::endl; return -EINVAL; } - int ret = init_bucket(bucket_name, bucket); + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); if (ret < 0) { cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 0b9f4dc356e2..10afb70c5d4e 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -300,18 +300,18 @@ static bool bucket_object_check_filter(const string& name) return rgw_obj::translate_raw_obj_to_obj_in_ns(obj, ns); } -int rgw_remove_object(RGWRados *store, rgw_bucket& bucket, std::string& object) +int rgw_remove_object(RGWRados *store, const string& bucket_owner, rgw_bucket& bucket, std::string& object) { RGWRadosCtx rctx(store); - rgw_obj obj(bucket,object); + rgw_obj obj(bucket, object); - int ret = store->delete_obj((void *)&rctx, obj); + int ret = store->delete_obj((void *)&rctx, bucket_owner, obj); return ret; } -int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children) +int rgw_remove_bucket(RGWRados *store, const string& bucket_owner, rgw_bucket& bucket, bool delete_children) { int ret; map stats; @@ -346,7 +346,7 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children) while (!objs.empty()) { std::vector::iterator it = objs.begin(); for (it = objs.begin(); it != objs.end(); ++it) { - ret = rgw_remove_object(store, bucket, (*it).name); + ret = rgw_remove_object(store, bucket_owner, bucket, (*it).name); if (ret < 0) return ret; } @@ -393,8 +393,6 @@ int RGWBucket::init(RGWRados *storage, RGWBucketAdminOpState& op_state) store = storage; - RGWBucketInfo bucket_info; - string user_id = op_state.get_user_id(); bucket_name = op_state.get_bucket_name(); RGWUserBuckets user_buckets; @@ -518,7 +516,7 @@ int RGWBucket::remove(RGWBucketAdminOpState& op_state, std::string *err_msg) bool delete_children = op_state.will_delete_children(); rgw_bucket bucket = op_state.get_bucket(); - int ret = rgw_remove_bucket(store, bucket, delete_children); + int ret = rgw_remove_bucket(store, bucket_info.owner, bucket, delete_children); if (ret < 0) { set_err_msg(err_msg, "unable to remove bucket" + cpp_strerror(-ret)); return ret; @@ -532,7 +530,7 @@ int RGWBucket::remove_object(RGWBucketAdminOpState& op_state, std::string *err_m rgw_bucket bucket = op_state.get_bucket(); std::string object_name = op_state.get_object_name(); - int ret = rgw_remove_object(store, bucket, object_name); + int ret = rgw_remove_object(store, bucket_info.owner, bucket, object_name); if (ret < 0) { set_err_msg(err_msg, "unable to remove object" + cpp_strerror(-ret)); return ret; diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index d0aed9553422..61b533c5a80e 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -104,8 +104,8 @@ extern int rgw_read_user_buckets(RGWRados *store, string user_id, RGWUserBuckets extern int rgw_link_bucket(RGWRados *store, string user_id, rgw_bucket& bucket, time_t creation_time, bool update_entrypoint = true); extern int rgw_unlink_bucket(RGWRados *store, string user_id, const string& bucket_name, bool update_entrypoint = true); -extern int rgw_remove_object(RGWRados *store, rgw_bucket& bucket, std::string& object); -extern int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children); +extern int rgw_remove_object(RGWRados *store, const string& bucket_owner, rgw_bucket& bucket, std::string& object); +extern int rgw_remove_bucket(RGWRados *store, const string& bucket_owner, rgw_bucket& bucket, bool delete_children); extern int rgw_bucket_set_attrs(RGWRados *store, rgw_bucket& obj, map& attrs, @@ -185,6 +185,8 @@ class RGWBucket bool failure; + RGWBucketInfo bucket_info; + private: public: diff --git a/src/rgw/rgw_cache.h b/src/rgw/rgw_cache.h index 68720d0e6ac3..dfc49c9ca3c5 100644 --- a/src/rgw/rgw_cache.h +++ b/src/rgw/rgw_cache.h @@ -199,7 +199,8 @@ public: map& attrs, RGWObjCategory category, int flags, map* rmattrs, const bufferlist *data, RGWObjManifest *manifest, const string *ptag, list *remove_objs, - bool modify_version, RGWObjVersionTracker *objv_tracker, time_t set_mtime); + bool modify_version, RGWObjVersionTracker *objv_tracker, time_t set_mtime, + const string& owner); int put_obj_data(void *ctx, rgw_obj& obj, const char *data, off_t ofs, size_t len, bool exclusive); @@ -208,7 +209,7 @@ public: int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch, map *attrs, bufferlist *first_chunk, RGWObjVersionTracker *objv_tracker); - int delete_obj(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_tracker); + int delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& obj, RGWObjVersionTracker *objv_tracker); }; template @@ -224,13 +225,13 @@ void RGWCache::normalize_bucket_and_obj(rgw_bucket& src_bucket, string& src_o } template -int RGWCache::delete_obj(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) +int RGWCache::delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) { rgw_bucket bucket; string oid; normalize_bucket_and_obj(obj.bucket, obj.object, bucket, oid); if (bucket.name[0] != '.') - return T::delete_obj(ctx, obj, objv_tracker); + return T::delete_obj_impl(ctx, bucket_owner, obj, objv_tracker); string name = normal_name(obj); cache.remove(name); @@ -238,7 +239,7 @@ int RGWCache::delete_obj(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_ ObjectCacheInfo info; distribute_cache(name, obj, info, REMOVE_OBJ); - return T::delete_obj(ctx, obj, objv_tracker); + return T::delete_obj_impl(ctx, bucket_owner, obj, objv_tracker); } template @@ -379,7 +380,8 @@ int RGWCache::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, time_ map& attrs, RGWObjCategory category, int flags, map* rmattrs, const bufferlist *data, RGWObjManifest *manifest, const string *ptag, list *remove_objs, - bool modify_version, RGWObjVersionTracker *objv_tracker, time_t set_mtime) + bool modify_version, RGWObjVersionTracker *objv_tracker, time_t set_mtime, + const string& owner) { rgw_bucket bucket; string oid; @@ -401,7 +403,7 @@ int RGWCache::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, time_ } } int ret = T::put_obj_meta_impl(ctx, obj, size, mtime, attrs, category, flags, rmattrs, data, manifest, ptag, remove_objs, - modify_version, objv_tracker, set_mtime); + modify_version, objv_tracker, set_mtime, owner); if (cacheable) { string name = normal_name(bucket, oid); if (ret >= 0) { diff --git a/src/rgw/rgw_metadata.cc b/src/rgw/rgw_metadata.cc index 1dd6107dc905..4307ce9ce6b4 100644 --- a/src/rgw/rgw_metadata.cc +++ b/src/rgw/rgw_metadata.cc @@ -600,7 +600,7 @@ int RGWMetadataManager::remove_entry(RGWMetadataHandler *handler, string& key, R rgw_obj obj(bucket, oid); - ret = store->delete_obj(NULL, obj, objv_tracker); + ret = store->delete_system_obj(NULL, obj, objv_tracker); /* cascading ret into post_modify() */ ret = post_modify(handler, section, key, log_data, objv_tracker, ret); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index bd73a239a4bf..d07cc1bba1d6 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1288,7 +1288,8 @@ protected: int do_complete(string& etag, time_t *mtime, time_t set_mtime, map& attrs); public: - RGWPutObjProcessor_Multipart(uint64_t _p, req_state *_s) : RGWPutObjProcessor_Atomic(_s->bucket, _s->object_str, _p, _s->req_id), s(_s) {} + RGWPutObjProcessor_Multipart(const string& bucket_owner, uint64_t _p, req_state *_s) : + RGWPutObjProcessor_Atomic(bucket_owner, _s->bucket, _s->object_str, _p, _s->req_id), s(_s) {} }; int RGWPutObjProcessor_Multipart::prepare(RGWRados *store, void *obj_ctx) @@ -1322,6 +1323,7 @@ int RGWPutObjProcessor_Multipart::do_complete(string& etag, time_t *mtime, time_ RGWRados::PutObjMetaExtraParams params; params.set_mtime = set_mtime; params.mtime = mtime; + params.owner = s->owner.get_id(); int r = store->put_obj_meta(obj_ctx, head_obj, s->obj_size, attrs, RGW_OBJ_CATEGORY_MAIN, 0, params); if (r < 0) @@ -1357,10 +1359,12 @@ RGWPutObjProcessor *RGWPutObj::select_processor() uint64_t part_size = s->cct->_conf->rgw_obj_stripe_size; + const string& bucket_owner = s->bucket_owner.get_id(); + if (!multipart) { - processor = new RGWPutObjProcessor_Atomic(s->bucket, s->object_str, part_size, s->req_id); + processor = new RGWPutObjProcessor_Atomic(bucket_owner, s->bucket, s->object_str, part_size, s->req_id); } else { - processor = new RGWPutObjProcessor_Multipart(part_size, s); + processor = new RGWPutObjProcessor_Multipart(bucket_owner, part_size, s); } return processor; @@ -1411,7 +1415,7 @@ void RGWPutObj::execute() if (!chunked_upload) { /* with chunked upload we don't know how big is the upload. we also check sizes at the end anyway */ - ret = store->check_quota(s->bucket, bucket_quota, s->content_length); + ret = store->check_quota(s->bucket_owner.get_id(), s->bucket, bucket_quota, s->content_length); if (ret < 0) { goto done; } @@ -1461,7 +1465,7 @@ void RGWPutObj::execute() s->obj_size = ofs; perfcounter->inc(l_rgw_put_b, s->obj_size); - ret = store->check_quota(s->bucket, bucket_quota, s->obj_size); + ret = store->check_quota(s->bucket_owner.get_id(), s->bucket, bucket_quota, s->obj_size); if (ret < 0) { goto done; } @@ -1517,7 +1521,7 @@ RGWPutObjProcessor *RGWPostObj::select_processor() uint64_t part_size = s->cct->_conf->rgw_obj_stripe_size; - processor = new RGWPutObjProcessor_Atomic(s->bucket, s->object_str, part_size, s->req_id); + processor = new RGWPutObjProcessor_Atomic(s->bucket_owner.get_id(), s->bucket, s->object_str, part_size, s->req_id); return processor; } @@ -1699,7 +1703,7 @@ void RGWDeleteObj::execute() rgw_obj obj(s->bucket, s->object_str); if (s->object) { store->set_atomic(s->obj_ctx, obj); - ret = store->delete_obj(s->obj_ctx, obj); + ret = store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), obj); } } @@ -2191,7 +2195,7 @@ void RGWInitMultipart::execute() obj.init_ns(s->bucket, tmp_obj_name, mp_ns); // the meta object will be indexed with 0 size, we c - ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL); + ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL, s->owner.get_id()); } while (ret == -EEXIST); } @@ -2381,6 +2385,7 @@ void RGWCompleteMultipart::execute() extra_params.remove_objs = &remove_objs; extra_params.ptag = &s->req_id; /* use req_id as operation tag */ + extra_params.owner = s->owner.get_id(); ret = store->put_obj_meta(s->obj_ctx, target_obj, ofs, attrs, RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, @@ -2390,7 +2395,7 @@ void RGWCompleteMultipart::execute() // remove the upload obj meta_obj.init_ns(s->bucket, meta_oid, mp_ns); - store->delete_obj(s->obj_ctx, meta_obj); + store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), meta_obj); } int RGWAbortMultipart::verify_permission() @@ -2413,6 +2418,7 @@ void RGWAbortMultipart::execute() map attrs; rgw_obj meta_obj; RGWMPObj mp; + const string& owner = s->bucket_owner.get_id(); if (upload_id.empty() || s->object_str.empty()) return; @@ -2431,7 +2437,7 @@ void RGWAbortMultipart::execute() string oid = mp.get_part(obj_iter->second.num); rgw_obj obj; obj.init_ns(s->bucket, oid, mp_ns); - ret = store->delete_obj(s->obj_ctx, obj); + ret = store->delete_obj(s->obj_ctx, owner, obj); if (ret < 0 && ret != -ENOENT) return; } else { @@ -2439,7 +2445,7 @@ void RGWAbortMultipart::execute() map::iterator oiter; for (oiter = manifest.objs.begin(); oiter != manifest.objs.end(); ++oiter) { RGWObjManifestPart& part = oiter->second; - ret = store->delete_obj(s->obj_ctx, part.loc); + ret = store->delete_obj(s->obj_ctx, owner, part.loc); if (ret < 0 && ret != -ENOENT) return; } @@ -2447,7 +2453,7 @@ void RGWAbortMultipart::execute() } // and also remove the metadata obj meta_obj.init_ns(s->bucket, meta_oid, mp_ns); - ret = store->delete_obj(s->obj_ctx, meta_obj); + ret = store->delete_obj(s->obj_ctx, owner, meta_obj); if (ret == -ENOENT) { ret = -ERR_NO_SUCH_BUCKET; } @@ -2579,7 +2585,7 @@ void RGWDeleteMultiObj::execute() rgw_obj obj(bucket,(*iter)); store->set_atomic(s->obj_ctx, obj); - ret = store->delete_obj(s->obj_ctx, obj); + ret = store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), obj); result = make_pair(*iter, ret); send_partial_response(result); diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc index 66609ca723c2..2b292df5a48e 100644 --- a/src/rgw/rgw_quota.cc +++ b/src/rgw/rgw_quota.cc @@ -46,7 +46,7 @@ public: } int get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats, RGWQuotaInfo& quota); - void adjust_bucket_stats(rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes); + void adjust_bucket_stats(const string& bucket_owner, rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes); bool can_use_cached_stats(RGWQuotaInfo& quota, RGWBucketStats& stats); @@ -270,7 +270,7 @@ public: }; -void RGWBucketStatsCache::adjust_bucket_stats(rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes) +void RGWBucketStatsCache::adjust_bucket_stats(const string& bucket_owner, rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes) { RGWBucketStatsUpdate update(objs_delta, added_bytes, removed_bytes); stats_map.find_and_update(bucket, NULL, &update); @@ -282,7 +282,7 @@ class RGWQuotaHandlerImpl : public RGWQuotaHandler { RGWBucketStatsCache stats_cache; public: RGWQuotaHandlerImpl(RGWRados *_store) : store(_store), stats_cache(_store) {} - virtual int check_quota(rgw_bucket& bucket, RGWQuotaInfo& bucket_quota, + virtual int check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& bucket_quota, uint64_t num_objs, uint64_t size) { uint64_t size_kb = rgw_rounded_kb(size); if (!bucket_quota.enabled) { @@ -315,8 +315,8 @@ public: return 0; } - virtual void update_stats(rgw_bucket& bucket, int obj_delta, uint64_t added_bytes, uint64_t removed_bytes) { - stats_cache.adjust_bucket_stats(bucket, obj_delta, added_bytes, removed_bytes); + virtual void update_stats(const string& bucket_owner, rgw_bucket& bucket, int obj_delta, uint64_t added_bytes, uint64_t removed_bytes) { + stats_cache.adjust_bucket_stats(bucket_owner, bucket, obj_delta, added_bytes, removed_bytes); }; }; diff --git a/src/rgw/rgw_quota.h b/src/rgw/rgw_quota.h index 2f8f28e85a2e..4c6b4262a09e 100644 --- a/src/rgw/rgw_quota.h +++ b/src/rgw/rgw_quota.h @@ -62,10 +62,10 @@ public: RGWQuotaHandler() {} virtual ~RGWQuotaHandler() { } - virtual int check_quota(rgw_bucket& bucket, RGWQuotaInfo& bucket_quota, + virtual int check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& bucket_quota, uint64_t num_objs, uint64_t size) = 0; - virtual void update_stats(rgw_bucket& bucket, int obj_delta, uint64_t added_bytes, uint64_t removed_bytes) = 0; + virtual void update_stats(const string& bucket_owner, rgw_bucket& bucket, int obj_delta, uint64_t added_bytes, uint64_t removed_bytes) = 0; static RGWQuotaHandler *generate_handler(RGWRados *store); static void free_handler(RGWQuotaHandler *handler); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 391c3a85f269..c56d994a57a1 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -562,7 +562,7 @@ RGWPutObjProcessor::~RGWPutObjProcessor() list::iterator iter; for (iter = objs.begin(); iter != objs.end(); ++iter) { rgw_obj& obj = *iter; - int r = store->delete_obj(obj_ctx, obj); + int r = store->delete_obj(obj_ctx, bucket_owner, obj); if (r < 0 && r != -ENOENT) { ldout(store->ctx(), 0) << "WARNING: failed to remove obj (" << obj << "), leaked" << dendl; } @@ -595,6 +595,7 @@ int RGWPutObjProcessor_Plain::do_complete(string& etag, time_t *mtime, time_t se params.set_mtime = set_mtime; params.mtime = mtime; params.data = &data; + params.owner = bucket_owner; int r = store->put_obj_meta(obj_ctx, obj, data.length(), attrs, RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, @@ -820,6 +821,7 @@ int RGWPutObjProcessor_Atomic::do_complete(string& etag, time_t *mtime, time_t s extra_params.ptag = &unique_tag; /* use req_id as operation tag */ extra_params.mtime = mtime; extra_params.set_mtime = set_mtime; + extra_params.owner = bucket_owner; r = store->put_obj_meta(obj_ctx, head_obj, obj_len, attrs, RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, @@ -2262,7 +2264,8 @@ int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, list *remove_objs, bool modify_version, RGWObjVersionTracker *objv_tracker, - time_t set_mtime) + time_t set_mtime, + const string& bucket_owner) { rgw_bucket bucket; std::string oid, key; @@ -2394,7 +2397,7 @@ int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, if (state) { /* update quota cache */ - quota_handler->update_stats(bucket, (state->exists ? 0 : 1), size, state->size); + quota_handler->update_stats(bucket_owner, bucket, (state->exists ? 0 : 1), size, state->size); } return 0; @@ -2639,7 +2642,7 @@ int RGWRados::copy_obj(void *ctx, string tag; append_rand_alpha(cct, tag, tag, 32); - RGWPutObjProcessor_Atomic processor(dest_obj.bucket, dest_obj.object, + RGWPutObjProcessor_Atomic processor(dest_bucket_info.owner, dest_obj.bucket, dest_obj.object, cct->_conf->rgw_obj_stripe_size, tag); ret = processor.prepare(this, ctx); if (ret < 0) @@ -2774,7 +2777,7 @@ set_err_state: return 0; } else if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */ - return copy_obj_data(ctx, &handle, end, dest_obj, src_obj, mtime, src_attrs, category, ptag, err); + return copy_obj_data(ctx, dest_bucket_info.owner, &handle, end, dest_obj, src_obj, mtime, src_attrs, category, ptag, err); } map::iterator miter = astate->manifest.objs.begin(); @@ -2848,6 +2851,7 @@ set_err_state: ep.data = &first_chunk; ep.manifest = pmanifest; ep.ptag = &tag; + ep.owner = dest_bucket_info.owner; ret = put_obj_meta(ctx, dest_obj, end + 1, src_attrs, category, PUT_OBJ_CREATE, ep); @@ -2879,6 +2883,7 @@ done_ret: int RGWRados::copy_obj_data(void *ctx, + const string& owner, void **handle, off_t end, rgw_obj& dest_obj, rgw_obj& src_obj, @@ -2947,6 +2952,7 @@ int RGWRados::copy_obj_data(void *ctx, ep.data = &first_chunk; ep.manifest = &manifest; ep.ptag = ptag; + ep.owner = owner; ret = put_obj_meta(ctx, dest_obj, end + 1, attrs, category, PUT_OBJ_CREATE, ep); if (mtime) @@ -2954,7 +2960,7 @@ int RGWRados::copy_obj_data(void *ctx, return ret; done_err: - delete_obj(ctx, shadow_obj); + delete_obj(ctx, owner, shadow_obj); return r; } @@ -3205,7 +3211,7 @@ int RGWRados::defer_gc(void *ctx, rgw_obj& obj) * obj: name of the object to delete * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) +int RGWRados::delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) { rgw_bucket bucket; std::string oid, key; @@ -3268,17 +3274,29 @@ int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj, RGWObjVersionTracker *obj if (state) { /* update quota cache */ - quota_handler->update_stats(bucket, -1, 0, state->size); + quota_handler->update_stats(bucket_owner, bucket, -1, 0, state->size); } return 0; } -int RGWRados::delete_obj(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) +int RGWRados::delete_obj(void *ctx, const string& bucket_owner, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) { int r; - r = delete_obj_impl(ctx, obj, objv_tracker); + r = delete_obj_impl(ctx, bucket_owner, obj, objv_tracker); + if (r == -ECANCELED) + r = 0; + + return r; +} + +int RGWRados::delete_system_obj(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_tracker) +{ + int r; + + string no_owner; + r = delete_obj_impl(ctx, no_owner, obj, objv_tracker); if (r == -ECANCELED) r = 0; @@ -5711,9 +5729,9 @@ int RGWRados::cls_user_remove_bucket(rgw_obj& obj, const cls_user_bucket& bucket return 0; } -int RGWRados::check_quota(rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size) +int RGWRados::check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size) { - return quota_handler->check_quota(bucket, quota_info, 1, obj_size); + return quota_handler->check_quota(bucket_owner, bucket, quota_info, 1, obj_size); } class IntentLogNameFilter : public RGWAccessListFilter @@ -5811,6 +5829,8 @@ int RGWRados::process_intent_log(rgw_bucket& bucket, string& oid, bufferlist::iterator iter; off_t off; + string no_owner; + while (!eof || !iter.end()) { off = iter.get_off(); if (!eof && (bl.length() - off) < chunk / 2) { @@ -5853,7 +5873,7 @@ int RGWRados::process_intent_log(rgw_bucket& bucket, string& oid, complete = false; break; } - r = delete_obj(NULL, entry.obj); + r = delete_obj(NULL, no_owner, entry.obj); if (r < 0 && r != -ENOENT) { cerr << "failed to remove obj: " << entry.obj << std::endl; complete = false; @@ -5890,7 +5910,7 @@ int RGWRados::process_intent_log(rgw_bucket& bucket, string& oid, rgw_obj obj(bucket, oid); cout << "completed intent log: " << obj << (purge ? ", purging it" : "") << std::endl; if (purge) { - r = delete_obj(NULL, obj); + r = delete_system_obj(NULL, obj); if (r < 0) cerr << "failed to remove obj: " << obj << std::endl; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 14e898eab1b0..1c66d49a555d 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -186,6 +186,7 @@ protected: RGWRados *store; void *obj_ctx; bool is_complete; + string bucket_owner; virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime, map& attrs) = 0; @@ -195,7 +196,7 @@ protected: objs.push_back(obj); } public: - RGWPutObjProcessor() : store(NULL), obj_ctx(NULL), is_complete(false) {} + RGWPutObjProcessor(const string& _bo) : store(NULL), obj_ctx(NULL), is_complete(false), bucket_owner(_bo) {} virtual ~RGWPutObjProcessor(); virtual int prepare(RGWRados *_store, void *_o) { store = _store; @@ -223,7 +224,8 @@ protected: public: int throttle_data(void *handle) { return 0; } - RGWPutObjProcessor_Plain(rgw_bucket& b, const string& o) : bucket(b), obj_str(o), ofs(0) {} + RGWPutObjProcessor_Plain(const string& bucket_owner, rgw_bucket& b, const string& o) : RGWPutObjProcessor(bucket_owner), + bucket(b), obj_str(o), ofs(0) {} }; struct put_obj_aio_info { @@ -248,7 +250,7 @@ protected: public: int throttle_data(void *handle); - RGWPutObjProcessor_Aio() : max_chunks(RGW_MAX_PENDING_CHUNKS), obj_len(0) {} + RGWPutObjProcessor_Aio(const string& bucket_owner) : RGWPutObjProcessor(bucket_owner), max_chunks(RGW_MAX_PENDING_CHUNKS), obj_len(0) {} virtual ~RGWPutObjProcessor_Aio() { drain_pending(); } @@ -288,7 +290,9 @@ protected: public: ~RGWPutObjProcessor_Atomic() {} - RGWPutObjProcessor_Atomic(rgw_bucket& _b, const string& _o, uint64_t _p, const string& _t) : part_size(_p), + RGWPutObjProcessor_Atomic(const string& bucket_owner, rgw_bucket& _b, const string& _o, uint64_t _p, const string& _t) : + RGWPutObjProcessor_Aio(bucket_owner), + part_size(_p), cur_part_ofs(0), next_part_ofs(_p), cur_part_id(0), @@ -874,13 +878,14 @@ class RGWRados v.push_back(info); return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true, false); } - int delete_obj_impl(void *ctx, rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker); int complete_atomic_overwrite(RGWRadosCtx *rctx, RGWObjState *state, rgw_obj& obj); int update_placement_map(); int store_bucket_info(RGWBucketInfo& info, map *pattrs, RGWObjVersionTracker *objv_tracker, bool exclusive); protected: + virtual int delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker); + CephContext *cct; librados::Rados *rados; librados::IoCtx gc_pool_ctx; // .rgw.gc @@ -1038,6 +1043,7 @@ public: bool modify_version; RGWObjVersionTracker *objv_tracker; time_t set_mtime; + string owner; PutObjMetaExtraParams() : mtime(NULL), rmattrs(NULL), data(NULL), manifest(NULL), ptag(NULL), @@ -1051,21 +1057,22 @@ public: map* rmattrs, const bufferlist *data, RGWObjManifest *manifest, const string *ptag, list *remove_objs, bool modify_version, RGWObjVersionTracker *objv_tracker, - time_t set_mtime /* 0 for don't set */); + time_t set_mtime /* 0 for don't set */, + const string& owner); virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime, map& attrs, RGWObjCategory category, int flags, - const bufferlist *data = NULL) { + const string& owner, const bufferlist *data = NULL) { return put_obj_meta_impl(ctx, obj, size, mtime, attrs, category, flags, NULL, data, NULL, NULL, NULL, - false, NULL, 0); + false, NULL, 0, owner); } virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, map& attrs, RGWObjCategory category, int flags, PutObjMetaExtraParams& params) { return put_obj_meta_impl(ctx, obj, size, params.mtime, attrs, category, flags, params.rmattrs, params.data, params.manifest, params.ptag, params.remove_objs, - params.modify_version, params.objv_tracker, params.set_mtime); + params.modify_version, params.objv_tracker, params.set_mtime, params.owner); } virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data, @@ -1161,6 +1168,7 @@ public: void *progress_data); int copy_obj_data(void *ctx, + const string& owner, void **handle, off_t end, rgw_obj& dest_obj, rgw_obj& src_obj, @@ -1181,7 +1189,8 @@ public: int bucket_suspended(rgw_bucket& bucket, bool *suspended); /** Delete an object.*/ - virtual int delete_obj(void *ctx, rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL); + virtual int delete_obj(void *ctx, const string& bucket_owner, rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL); + virtual int delete_system_obj(void *ctx, rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL); /** Remove an object from the bucket index */ int delete_obj_index(rgw_obj& obj); @@ -1421,7 +1430,7 @@ public: int cls_user_add_bucket(rgw_obj& obj, list& entries); int cls_user_remove_bucket(rgw_obj& obj, const cls_user_bucket& bucket); - int check_quota(rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size); + int check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size); string unique_id(uint64_t unique_num) { char buf[32]; diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index dc529e3d48d4..d8bbafabfb55 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -239,7 +239,7 @@ extern int rgw_get_user_info_by_access_key(RGWRados *store, string& access_key, int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key) { rgw_obj obj(store->zone.user_keys_pool, access_key.id); - int ret = store->delete_obj(NULL, obj); + int ret = store->delete_system_obj(NULL, obj); return ret; } @@ -261,14 +261,14 @@ int rgw_remove_uid_index(RGWRados *store, string& uid) int rgw_remove_email_index(RGWRados *store, string& email) { rgw_obj obj(store->zone.user_email_pool, email); - int ret = store->delete_obj(NULL, obj); + int ret = store->delete_system_obj(NULL, obj); return ret; } int rgw_remove_swift_name_index(RGWRados *store, string& swift_name) { rgw_obj obj(store->zone.user_swift_pool, swift_name); - int ret = store->delete_obj(NULL, obj); + int ret = store->delete_system_obj(NULL, obj); return ret; } @@ -330,7 +330,7 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& ob rgw_obj email_obj(store->zone.user_email_pool, info.user_email); ldout(store->ctx(), 10) << "removing email index: " << info.user_email << dendl; - ret = store->delete_obj(NULL, email_obj); + ret = store->delete_system_obj(NULL, email_obj); if (ret < 0 && ret != -ENOENT) { ldout(store->ctx(), 0) << "ERROR: could not remove " << info.user_id << ":" << email_obj << ", should be fixed (err=" << ret << ")" << dendl; return ret; @@ -340,7 +340,7 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& ob rgw_get_buckets_obj(info.user_id, buckets_obj_id); rgw_obj uid_bucks(store->zone.user_uid_pool, buckets_obj_id); ldout(store->ctx(), 10) << "removing user buckets index" << dendl; - ret = store->delete_obj(NULL, uid_bucks); + ret = store->delete_system_obj(NULL, uid_bucks); if (ret < 0 && ret != -ENOENT) { ldout(store->ctx(), 0) << "ERROR: could not remove " << info.user_id << ":" << uid_bucks << ", should be fixed (err=" << ret << ")" << dendl; return ret; @@ -1774,7 +1774,7 @@ int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg) std::map::iterator it; for (it = m.begin(); it != m.end(); ++it) { - ret = rgw_remove_bucket(store, ((*it).second).bucket, true); + ret = rgw_remove_bucket(store, uid, ((*it).second).bucket, true); if (ret < 0) { set_err_msg(err_msg, "unable to delete user data"); return ret;